From 35cbd867d6ccdfd975ec9ae77b5ef9ccf271ee44 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 12 Mar 2018 00:21:12 -0400 Subject: [PATCH 001/512] initial commit --- third_party/android/.gitignore | 10 + third_party/android/app/build.gradle | 51 ++ .../android/app/src/main/AndroidManifest.xml | 39 ++ .../com/example/fluttersvg/MainActivity.java | 14 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../app/src/main/res/values/styles.xml | 8 + third_party/android/build.gradle | 29 ++ third_party/android/gradle.properties | 1 + .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + third_party/android/gradlew | 160 +++++++ third_party/android/gradlew.bat | 90 ++++ third_party/android/settings.gradle | 15 + third_party/assets/aa.svg | 5 + third_party/assets/alphachannel.svg | 5 + third_party/flutter_svg.iml | 17 + third_party/flutter_svg_android.iml | 26 ++ third_party/ios/.gitignore | 42 ++ .../ios/Flutter/AppFrameworkInfo.plist | 30 ++ third_party/ios/Flutter/Debug.xcconfig | 1 + third_party/ios/Flutter/Release.xcconfig | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 436 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/Runner.xcscheme | 93 ++++ .../contents.xcworkspacedata | 7 + third_party/ios/Runner/AppDelegate.h | 6 + third_party/ios/Runner/AppDelegate.m | 12 + .../AppIcon.appiconset/Contents.json | 122 +++++ .../Icon-App-1024x1024@1x.png | Bin 0 -> 11112 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 564 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 1588 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 1025 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 1716 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 1920 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 1895 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 3831 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 1888 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 3294 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 3612 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + .../Runner/Base.lproj/LaunchScreen.storyboard | 37 ++ .../ios/Runner/Base.lproj/Main.storyboard | 26 ++ third_party/ios/Runner/Info.plist | 49 ++ third_party/ios/Runner/main.m | 9 + third_party/lib/main.dart | 83 ++++ third_party/lib/src/elements.dart | 64 +++ third_party/lib/src/parsers.dart | 35 ++ third_party/lib/src/paths.dart | 0 third_party/lib/src/svg.dart | 29 ++ third_party/lib/svg.dart | 1 + third_party/pubspec.lock | 412 +++++++++++++++++ third_party/pubspec.yaml | 61 +++ third_party/test/widget_test.dart | 29 ++ 66 files changed, 2108 insertions(+) create mode 100644 third_party/android/.gitignore create mode 100644 third_party/android/app/build.gradle create mode 100644 third_party/android/app/src/main/AndroidManifest.xml create mode 100644 third_party/android/app/src/main/java/com/example/fluttersvg/MainActivity.java create mode 100644 third_party/android/app/src/main/res/drawable/launch_background.xml create mode 100644 third_party/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 third_party/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 third_party/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 third_party/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 third_party/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 third_party/android/app/src/main/res/values/styles.xml create mode 100644 third_party/android/build.gradle create mode 100644 third_party/android/gradle.properties create mode 100644 third_party/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 third_party/android/gradle/wrapper/gradle-wrapper.properties create mode 100755 third_party/android/gradlew create mode 100644 third_party/android/gradlew.bat create mode 100644 third_party/android/settings.gradle create mode 100644 third_party/assets/aa.svg create mode 100644 third_party/assets/alphachannel.svg create mode 100644 third_party/flutter_svg.iml create mode 100644 third_party/flutter_svg_android.iml create mode 100644 third_party/ios/.gitignore create mode 100644 third_party/ios/Flutter/AppFrameworkInfo.plist create mode 100644 third_party/ios/Flutter/Debug.xcconfig create mode 100644 third_party/ios/Flutter/Release.xcconfig create mode 100644 third_party/ios/Runner.xcodeproj/project.pbxproj create mode 100644 third_party/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 third_party/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 third_party/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 third_party/ios/Runner/AppDelegate.h create mode 100644 third_party/ios/Runner/AppDelegate.m create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 third_party/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 third_party/ios/Runner/Base.lproj/Main.storyboard create mode 100644 third_party/ios/Runner/Info.plist create mode 100644 third_party/ios/Runner/main.m create mode 100644 third_party/lib/main.dart create mode 100644 third_party/lib/src/elements.dart create mode 100644 third_party/lib/src/parsers.dart create mode 100644 third_party/lib/src/paths.dart create mode 100644 third_party/lib/src/svg.dart create mode 100644 third_party/lib/svg.dart create mode 100644 third_party/pubspec.lock create mode 100644 third_party/pubspec.yaml create mode 100644 third_party/test/widget_test.dart diff --git a/third_party/android/.gitignore b/third_party/android/.gitignore new file mode 100644 index 000000000000..65b7315af1b6 --- /dev/null +++ b/third_party/android/.gitignore @@ -0,0 +1,10 @@ +*.iml +*.class +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +GeneratedPluginRegistrant.java diff --git a/third_party/android/app/build.gradle b/third_party/android/app/build.gradle new file mode 100644 index 000000000000..df6aec923086 --- /dev/null +++ b/third_party/android/app/build.gradle @@ -0,0 +1,51 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 27 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.fluttersvg" + minSdkVersion 16 + targetSdkVersion 27 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.1' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' +} diff --git a/third_party/android/app/src/main/AndroidManifest.xml b/third_party/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..a1ba572ecb51 --- /dev/null +++ b/third_party/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + diff --git a/third_party/android/app/src/main/java/com/example/fluttersvg/MainActivity.java b/third_party/android/app/src/main/java/com/example/fluttersvg/MainActivity.java new file mode 100644 index 000000000000..99570dfffe80 --- /dev/null +++ b/third_party/android/app/src/main/java/com/example/fluttersvg/MainActivity.java @@ -0,0 +1,14 @@ +package com.example.fluttersvg; + +import android.os.Bundle; + +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/third_party/android/app/src/main/res/drawable/launch_background.xml b/third_party/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 000000000000..304732f88420 --- /dev/null +++ b/third_party/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/third_party/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/third_party/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 diff --git a/third_party/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/third_party/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 diff --git a/third_party/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/third_party/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 diff --git a/third_party/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/third_party/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/third_party/android/app/src/main/res/values/styles.xml b/third_party/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000000..00fa4417cfbe --- /dev/null +++ b/third_party/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/third_party/android/build.gradle b/third_party/android/build.gradle new file mode 100644 index 000000000000..447688755cf4 --- /dev/null +++ b/third_party/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.0.1' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/third_party/android/gradle.properties b/third_party/android/gradle.properties new file mode 100644 index 000000000000..8bd86f680510 --- /dev/null +++ b/third_party/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/third_party/android/gradle/wrapper/gradle-wrapper.jar b/third_party/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..13372aef5e24af05341d49695ee84e5f9b594659 GIT binary patch literal 53636 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ⅅ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 H-+%o-(+5aQ literal 0 HcmV?d00001 diff --git a/third_party/android/gradle/wrapper/gradle-wrapper.properties b/third_party/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..aa901e1e0db2 --- /dev/null +++ b/third_party/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/third_party/android/gradlew b/third_party/android/gradlew new file mode 100755 index 000000000000..9d82f7891513 --- /dev/null +++ b/third_party/android/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/third_party/android/gradlew.bat b/third_party/android/gradlew.bat new file mode 100644 index 000000000000..aec99730b4e8 --- /dev/null +++ b/third_party/android/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/third_party/android/settings.gradle b/third_party/android/settings.gradle new file mode 100644 index 000000000000..5a2f14fb18f6 --- /dev/null +++ b/third_party/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/third_party/assets/aa.svg b/third_party/assets/aa.svg new file mode 100644 index 000000000000..2f2d26b165a7 --- /dev/null +++ b/third_party/assets/aa.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/third_party/assets/alphachannel.svg b/third_party/assets/alphachannel.svg new file mode 100644 index 000000000000..be7bf45d07ee --- /dev/null +++ b/third_party/assets/alphachannel.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/third_party/flutter_svg.iml b/third_party/flutter_svg.iml new file mode 100644 index 000000000000..485a35d430c6 --- /dev/null +++ b/third_party/flutter_svg.iml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/flutter_svg_android.iml b/third_party/flutter_svg_android.iml new file mode 100644 index 000000000000..0ca70ed93eaf --- /dev/null +++ b/third_party/flutter_svg_android.iml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ios/.gitignore b/third_party/ios/.gitignore new file mode 100644 index 000000000000..1e1aafd63360 --- /dev/null +++ b/third_party/ios/.gitignore @@ -0,0 +1,42 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/app.flx +/Flutter/app.zip +/Flutter/flutter_assets/ +/Flutter/App.framework +/Flutter/Flutter.framework +/Flutter/Generated.xcconfig +/ServiceDefinitions.json + +Pods/ diff --git a/third_party/ios/Flutter/AppFrameworkInfo.plist b/third_party/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000000..6c2de8086bcd --- /dev/null +++ b/third_party/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,30 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + UIRequiredDeviceCapabilities + + arm64 + + MinimumOSVersion + 8.0 + + diff --git a/third_party/ios/Flutter/Debug.xcconfig b/third_party/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000000..592ceee85b89 --- /dev/null +++ b/third_party/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/third_party/ios/Flutter/Release.xcconfig b/third_party/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000000..592ceee85b89 --- /dev/null +++ b/third_party/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/third_party/ios/Runner.xcodeproj/project.pbxproj b/third_party/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..f823283cee5b --- /dev/null +++ b/third_party/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,436 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ARCHS = arm64; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterSvg; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ARCHS = arm64; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterSvg; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/third_party/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/third_party/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..1d526a16ed0f --- /dev/null +++ b/third_party/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/third_party/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/third_party/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..1263ac84b105 --- /dev/null +++ b/third_party/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ios/Runner.xcworkspace/contents.xcworkspacedata b/third_party/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..1d526a16ed0f --- /dev/null +++ b/third_party/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/third_party/ios/Runner/AppDelegate.h b/third_party/ios/Runner/AppDelegate.h new file mode 100644 index 000000000000..cf210d213f27 --- /dev/null +++ b/third_party/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/third_party/ios/Runner/AppDelegate.m b/third_party/ios/Runner/AppDelegate.m new file mode 100644 index 000000000000..112becd13b36 --- /dev/null +++ b/third_party/ios/Runner/AppDelegate.m @@ -0,0 +1,12 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..d36b1fab2d9d --- /dev/null +++ b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d43d11e66f4de3da27ed045ca4fe38ad8b48094 GIT binary patch literal 11112 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 P-1+_A+?hGkL;m(J7kc&K literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..28c6bf03016f6c994b70f38d1b7346e5831b531f GIT binary patch literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f091b6b0bca859a3f474b03065bef75ba58a9e4c GIT binary patch literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ef06e7edb86cdfe0d15b4b0d98334a86163658 GIT binary patch literal 1716 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 literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f9ed8f5cee1c98386d13b17e89f719e83555b2 GIT binary patch literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..75b2d164a5a98e212cca15ea7bf2ab5de5108680 GIT binary patch literal 3831 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 literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c4df70d39da7941ef3f6dcb7f06a192d8dcb308d GIT binary patch literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000000..89c2725b70f1 --- /dev/null +++ b/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/third_party/ios/Runner/Base.lproj/LaunchScreen.storyboard b/third_party/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000000..f2e259c7c939 --- /dev/null +++ b/third_party/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ios/Runner/Base.lproj/Main.storyboard b/third_party/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000000..f3c28516fb38 --- /dev/null +++ b/third_party/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/ios/Runner/Info.plist b/third_party/ios/Runner/Info.plist new file mode 100644 index 000000000000..59d7e309a41b --- /dev/null +++ b/third_party/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + flutter_svg + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/third_party/ios/Runner/main.m b/third_party/ios/Runner/main.m new file mode 100644 index 000000000000..0ccc450011c4 --- /dev/null +++ b/third_party/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart new file mode 100644 index 000000000000..76fdd6134154 --- /dev/null +++ b/third_party/lib/main.dart @@ -0,0 +1,83 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart' show rootBundle; +import 'package:xml/xml.dart'; + +import 'package:flutter_svg/svg.dart'; + +void main() => runApp(new MyApp()); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return new MaterialApp( + title: 'Flutter Demo', + theme: new ThemeData( + // This is the theme of your application. + // + // Try running your application with "flutter run". You'll see the + // application has a blue toolbar. Then, without quitting the app, try + // changing the primarySwatch below to Colors.green and then invoke + // "hot reload" (press "r" in the console where you ran "flutter run", + // or press Run > Flutter Hot Reload in IntelliJ). Notice that the + // counter didn't reset back to zero; the application is not restarted. + primarySwatch: Colors.blue, + ), + home: new MyHomePage(title: 'Flutter Demo Home Page'), + ); + } +} + +class MyHomePage extends StatefulWidget { + MyHomePage({Key key, this.title}) : super(key: key); + + // This widget is the home page of your application. It is stateful, meaning + // that it has a State object (defined below) that contains fields that affect + // how it looks. + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + + @override + _MyHomePageState createState() => new _MyHomePageState(); +} + +class _MyHomePageState extends State { + XmlDocument _svgDoc; + + @override + void initState() { + super.initState(); + loadAsset('assets/aa.svg').then((xml) { + setState(() { + _svgDoc = xml; + }); + }); + } + + @override + Widget build(BuildContext context) { + return new Scaffold( + appBar: new AppBar( + title: new Text(widget.title), + ), + body: new Center( + child: new CustomPaint( + painter: new SvgPainter(_svgDoc), + size: const Size(300.0, 300.0), + ), + ), + ); + } +} + +Future loadAsset(String assetName) async { + final xml = await rootBundle.loadString(assetName); + return parse(xml); +} diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart new file mode 100644 index 000000000000..edc852afeb46 --- /dev/null +++ b/third_party/lib/src/elements.dart @@ -0,0 +1,64 @@ +import 'dart:ui'; + +import 'package:xml/xml.dart'; +import 'package:vector_math/vector_math_64.dart'; +import 'parsers.dart'; + +typedef SvgBaseElement SvgElementFactory(XmlElement el); + +abstract class SvgBaseElement { + final XmlElement _rawElement; + + static final Map _elements = { + 'circle': (el) => new SvgCircle(el), + 'path': (el) => new SvgPath(el), + }; + + void draw(XmlElement element, Canvas canvas); + + const SvgBaseElement._(this._rawElement); + + factory SvgBaseElement.fromXml(XmlElement element) { + final ret = _elements[element.name.local]; + if (ret == null) { + throw new UnsupportedError('${element.name.local} not impleemnted yet'); + } + + return ret(element); + } +} + +class SvgCircle extends SvgBaseElement { + const SvgCircle(XmlElement el) : super._(el); + + void draw(XmlElement el, Canvas canvas) { + final cx = double.parse(el.getAttribute('cx')); + final cy = double.parse(el.getAttribute('cy')); + final r = double.parse(el.getAttribute('r')); + final fill = parseColor(el.getAttribute('fill')); + final opacity = double.parse(el.getAttribute('opacity')); + final paint = new Paint()..color = fill.withAlpha((255 * opacity).toInt()); + canvas.drawCircle(new Offset(cx, cy), r, paint); + } +} + +class SvgPath extends SvgBaseElement { + const SvgPath(XmlElement el) : super._(el); + + void draw(XmlElement el, Canvas canvas) { + final d = el.getAttribute('d'); + final p = Path.parseSvgPathData(d); + final fill = parseColor(el.getAttribute('fill')); + final paint = new Paint()..color = fill; + // TODO: Actually implement a parser for this + // Maybe take logic from https://github.com/flutter/flutter/blob/master/dev/tools/vitool/lib/vitool.dart + if (el.getAttribute('transform') != null) { + final m = new Matrix4.identity(); + m.scale(0.1); + p.transform(m.storage); + canvas.scale(.1, .1); + } + canvas.drawPath(p, paint); + + } +} diff --git a/third_party/lib/src/parsers.dart b/third_party/lib/src/parsers.dart new file mode 100644 index 000000000000..6287c33a4704 --- /dev/null +++ b/third_party/lib/src/parsers.dart @@ -0,0 +1,35 @@ +import 'dart:ui'; + +Rect parseViewBox(String viewbox) { + if (viewbox == null || viewbox == '') { + return Rect.zero; + } + + final parts = viewbox.split(' '); + return new Rect.fromLTWH(double.parse(parts[0]), double.parse(parts[1]), + double.parse(parts[2]), double.parse(parts[3])); +} + +Color parseColor(String colorString) { + if (colorString[0] == '#') { + if (colorString.length == 4) { + final r = colorString[1]; + final g = colorString[2]; + final b = colorString[3]; + colorString = '#$r$r$g$g$b$b'; + } + int color = int.parse(colorString.substring(1), + radix: 16, onError: (source) => null); + + if (colorString.length == 7) { + return new Color(color |= 0x00000000ff000000); + } + + if (colorString.length == 9) { + return new Color(color); + } + } + + throw new ArgumentError.value( + colorString, "colorString", "Unknown color $colorString"); +} diff --git a/third_party/lib/src/paths.dart b/third_party/lib/src/paths.dart new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/third_party/lib/src/svg.dart b/third_party/lib/src/svg.dart new file mode 100644 index 000000000000..070e7633fe5d --- /dev/null +++ b/third_party/lib/src/svg.dart @@ -0,0 +1,29 @@ +import 'package:xml/xml.dart'; +import 'package:flutter/widgets.dart'; + +import 'package:flutter_svg/src/parsers.dart'; +import 'package:flutter_svg/src/elements.dart'; + +class SvgPainter extends CustomPainter { + final XmlDocument _rawSvg; + + SvgPainter(this._rawSvg); + + @override + void paint(Canvas canvas, Size size) { + if (_rawSvg == null) return; + var viewBox = + (_rawSvg.root.firstChild as XmlElement).getAttribute('viewBox'); + final vbRect = parseViewBox(viewBox); + canvas.scale(size.width / vbRect.size.width, size.height / vbRect.size.height); + for (var el in _rawSvg.root.firstChild.children) { + if (el is! XmlElement) continue; + final svgEl = new SvgBaseElement.fromXml(el); + svgEl.draw(el, canvas); + } + } + + @override + bool shouldRepaint(SvgPainter oldPainter) => + _rawSvg != null && oldPainter._rawSvg != _rawSvg; +} diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart new file mode 100644 index 000000000000..5eec5703cab1 --- /dev/null +++ b/third_party/lib/svg.dart @@ -0,0 +1 @@ +export 'package:flutter_svg/src/svg.dart'; diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock new file mode 100644 index 000000000000..9aae76200688 --- /dev/null +++ b/third_party/pubspec.lock @@ -0,0 +1,412 @@ +# Generated by pub +# See https://www.dartlang.org/tools/pub/glossary#lockfile +packages: + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "0.31.1" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.1" + async: + dependency: transitive + description: + name: async + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.6" + barback: + dependency: transitive + description: + name: barback + url: "https://pub.dartlang.org" + source: hosted + version: "0.15.2+14" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + charcode: + dependency: transitive + description: + name: charcode + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.1" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2+1" + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.6" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2+1" + csslib: + dependency: transitive + description: + name: csslib + url: "https://pub.dartlang.org" + source: hosted + version: "0.14.1" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + front_end: + dependency: transitive + description: + name: front_end + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0-alpha.9" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.5" + html: + dependency: transitive + description: + name: html + url: "https://pub.dartlang.org" + source: hosted + version: "0.13.2+2" + http: + dependency: transitive + description: + name: http + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.3+16" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.4" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.1" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.2+1" + isolate: + dependency: transitive + description: + name: isolate + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.1" + kernel: + dependency: transitive + description: + name: kernel + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0-alpha.9" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "0.11.3+1" + matcher: + dependency: transitive + description: + name: matcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.1+4" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.2" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.6" + mockito: + dependency: transitive + description: + name: mockito + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" + multi_server_socket: + dependency: transitive + description: + name: multi_server_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + node_preamble: + dependency: transitive + description: + name: node_preamble + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + package_resolver: + dependency: transitive + description: + name: package_resolver + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + path: + dependency: transitive + description: + name: path + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.1" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "1.7.5" + plugin: + dependency: transitive + description: + name: plugin + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.0+2" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.4" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.2" + quiver: + dependency: transitive + description: + name: quiver + url: "https://pub.dartlang.org" + source: hosted + version: "0.28.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.2" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + shelf_static: + dependency: transitive + description: + name: shelf_static + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.7" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.2" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.4" + source_maps: + dependency: transitive + description: + name: source_maps + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.4" + source_span: + dependency: transitive + description: + name: source_span + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.2" + stream_channel: + dependency: transitive + description: + name: stream_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.6.4" + string_scanner: + dependency: transitive + description: + name: string_scanner + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" + term_glyph: + dependency: transitive + description: + name: term_glyph + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + test: + dependency: transitive + description: + name: test + url: "https://pub.dartlang.org" + source: hosted + version: "0.12.32+1" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.5" + utf: + dependency: transitive + description: + name: utf + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.0+4" + vector_math: + dependency: "direct main" + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.5" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "0.9.7+7" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.7" + xml: + dependency: "direct main" + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.13" +sdks: + dart: ">=2.0.0-dev.23.0 <=2.0.0-edge.0d5cf900b021bf5c9fa593ffa12b15bcd1cc5fe0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml new file mode 100644 index 000000000000..eb7974b4f8a2 --- /dev/null +++ b/third_party/pubspec.yaml @@ -0,0 +1,61 @@ +name: flutter_svg +description: A new Flutter project. + +dependencies: + xml: any + vector_math: any + flutter: + sdk: flutter + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^0.1.0 + +dev_dependencies: + flutter_test: + sdk: flutter + + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/alphachannel.svg + - assets/aa.svg + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.io/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.io/custom-fonts/#from-packages diff --git a/third_party/test/widget_test.dart b/third_party/test/widget_test.dart new file mode 100644 index 000000000000..16cea800ac0c --- /dev/null +++ b/third_party/test/widget_test.dart @@ -0,0 +1,29 @@ +// This is a basic Flutter widget test. +// To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter +// provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to +// find child widgets in the widget tree, read text, and verify that the values of widget properties +// are correct. + +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_svg/main.dart'; + +void main() { + testWidgets('Counter increments smoke test', (WidgetTester tester) async { + // Build our app and trigger a frame. + await tester.pumpWidget(new MyApp()); + + // Verify that our counter starts at 0. + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsNothing); + + // Tap the '+' icon and trigger a frame. + await tester.tap(find.byIcon(Icons.add)); + await tester.pump(); + + // Verify that our counter has incremented. + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + }); +} From d00cc10024a50e586883f0b705e85fad7e960e4b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 12 Mar 2018 10:19:54 -0400 Subject: [PATCH 002/512] add more shapes, add more samples, start parsing transforms --- .../deborah_ufw/new-action-expander.svg | 14 ++ third_party/assets/deborah_ufw/new-camera.svg | 21 +++ .../assets/deborah_ufw/new-gif-button.svg | 32 ++++ third_party/assets/deborah_ufw/new-gif.svg | 30 ++++ third_party/assets/deborah_ufw/new-image.svg | 19 +++ .../assets/deborah_ufw/new-mention.svg | 22 +++ .../assets/deborah_ufw/new-pause-button.svg | 22 +++ .../assets/deborah_ufw/new-play-button.svg | 16 ++ .../assets/deborah_ufw/new-send-circle.svg | 27 ++++ third_party/assets/deborah_ufw/numeric_25.svg | 19 +++ third_party/lib/main.dart | 63 ++++---- third_party/lib/src/elements.dart | 138 +++++++++++++++--- third_party/lib/src/parsers.dart | 88 +++++++++++ third_party/lib/src/paths.dart | 0 third_party/lib/src/svg.dart | 11 +- third_party/pubspec.yaml | 10 ++ 16 files changed, 480 insertions(+), 52 deletions(-) create mode 100644 third_party/assets/deborah_ufw/new-action-expander.svg create mode 100644 third_party/assets/deborah_ufw/new-camera.svg create mode 100644 third_party/assets/deborah_ufw/new-gif-button.svg create mode 100644 third_party/assets/deborah_ufw/new-gif.svg create mode 100644 third_party/assets/deborah_ufw/new-image.svg create mode 100644 third_party/assets/deborah_ufw/new-mention.svg create mode 100644 third_party/assets/deborah_ufw/new-pause-button.svg create mode 100644 third_party/assets/deborah_ufw/new-play-button.svg create mode 100644 third_party/assets/deborah_ufw/new-send-circle.svg create mode 100644 third_party/assets/deborah_ufw/numeric_25.svg delete mode 100644 third_party/lib/src/paths.dart diff --git a/third_party/assets/deborah_ufw/new-action-expander.svg b/third_party/assets/deborah_ufw/new-action-expander.svg new file mode 100644 index 000000000000..3cbd1068517c --- /dev/null +++ b/third_party/assets/deborah_ufw/new-action-expander.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/third_party/assets/deborah_ufw/new-camera.svg b/third_party/assets/deborah_ufw/new-camera.svg new file mode 100644 index 000000000000..b49e595b6c94 --- /dev/null +++ b/third_party/assets/deborah_ufw/new-camera.svg @@ -0,0 +1,21 @@ + + + + + + + diff --git a/third_party/assets/deborah_ufw/new-gif-button.svg b/third_party/assets/deborah_ufw/new-gif-button.svg new file mode 100644 index 000000000000..2340bf1acfb6 --- /dev/null +++ b/third_party/assets/deborah_ufw/new-gif-button.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/third_party/assets/deborah_ufw/new-gif.svg b/third_party/assets/deborah_ufw/new-gif.svg new file mode 100644 index 000000000000..cf9e9cab65be --- /dev/null +++ b/third_party/assets/deborah_ufw/new-gif.svg @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/third_party/assets/deborah_ufw/new-image.svg b/third_party/assets/deborah_ufw/new-image.svg new file mode 100644 index 000000000000..ed41cff77c18 --- /dev/null +++ b/third_party/assets/deborah_ufw/new-image.svg @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/third_party/assets/deborah_ufw/new-mention.svg b/third_party/assets/deborah_ufw/new-mention.svg new file mode 100644 index 000000000000..085a7d41b8b8 --- /dev/null +++ b/third_party/assets/deborah_ufw/new-mention.svg @@ -0,0 +1,22 @@ + + + + + diff --git a/third_party/assets/deborah_ufw/new-pause-button.svg b/third_party/assets/deborah_ufw/new-pause-button.svg new file mode 100644 index 000000000000..90deeee9a5af --- /dev/null +++ b/third_party/assets/deborah_ufw/new-pause-button.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/third_party/assets/deborah_ufw/new-play-button.svg b/third_party/assets/deborah_ufw/new-play-button.svg new file mode 100644 index 000000000000..40799c91370e --- /dev/null +++ b/third_party/assets/deborah_ufw/new-play-button.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/third_party/assets/deborah_ufw/new-send-circle.svg b/third_party/assets/deborah_ufw/new-send-circle.svg new file mode 100644 index 000000000000..ab58e6b145fd --- /dev/null +++ b/third_party/assets/deborah_ufw/new-send-circle.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + diff --git a/third_party/assets/deborah_ufw/numeric_25.svg b/third_party/assets/deborah_ufw/numeric_25.svg new file mode 100644 index 000000000000..ea6f38c2b3d8 --- /dev/null +++ b/third_party/assets/deborah_ufw/numeric_25.svg @@ -0,0 +1,19 @@ + + + +icon-font/25/numeric_25 +Created with Sketch. + + + + diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 76fdd6134154..9cc02fa86213 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -6,6 +6,20 @@ import 'package:xml/xml.dart'; import 'package:flutter_svg/svg.dart'; +const List assetNames = const [ + 'assets/aa.svg', + 'assets/alphachannel.svg', + 'assets/deborah_ufw/new-action-expander.svg', + 'assets/deborah_ufw/new-camera.svg', + 'assets/deborah_ufw/new-gif-button.svg', + 'assets/deborah_ufw/new-gif.svg', + 'assets/deborah_ufw/new-image.svg', + 'assets/deborah_ufw/new-mention.svg', + 'assets/deborah_ufw/new-pause-button.svg', + 'assets/deborah_ufw/new-play-button.svg', + 'assets/deborah_ufw/new-send-circle.svg', + 'assets/deborah_ufw/numeric_25.svg', +]; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @@ -15,33 +29,15 @@ class MyApp extends StatelessWidget { return new MaterialApp( title: 'Flutter Demo', theme: new ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or press Run > Flutter Hot Reload in IntelliJ). Notice that the - // counter didn't reset back to zero; the application is not restarted. primarySwatch: Colors.blue, ), - home: new MyHomePage(title: 'Flutter Demo Home Page'), + home: new MyHomePage(title: 'Flutter SVG Demo'), ); } } class MyHomePage extends StatefulWidget { MyHomePage({Key key, this.title}) : super(key: key); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - final String title; @override @@ -49,14 +45,21 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - XmlDocument _svgDoc; + List _painters = new List(); @override void initState() { super.initState(); - loadAsset('assets/aa.svg').then((xml) { - setState(() { - _svgDoc = xml; + // loadAsset('assets/deborah_ufw/new-camera.svg').then((xml) { + // setState(() { + // _svgDoc = xml; + // }); + // }); + assetNames.forEach((assetName) { + loadAsset(assetName).then((xml) { + setState(() { + _painters.add(new SvgPainter(xml)); + }); }); }); } @@ -67,11 +70,15 @@ class _MyHomePageState extends State { appBar: new AppBar( title: new Text(widget.title), ), - body: new Center( - child: new CustomPaint( - painter: new SvgPainter(_svgDoc), - size: const Size(300.0, 300.0), - ), + body: new GridView.extent( + maxCrossAxisExtent: 150.0, + padding: const EdgeInsets.all(4.0), + mainAxisSpacing: 4.0, + crossAxisSpacing: 4.0, + children: _painters.map((painter) { + return new CustomPaint( + painter: painter, size: const Size(150.0, 150.0)); + }).toList(), ), ); } diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index edc852afeb46..aa36fa90332f 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -1,4 +1,5 @@ import 'dart:ui'; +import 'dart:typed_data'; import 'package:xml/xml.dart'; import 'package:vector_math/vector_math_64.dart'; @@ -7,16 +8,19 @@ import 'parsers.dart'; typedef SvgBaseElement SvgElementFactory(XmlElement el); abstract class SvgBaseElement { - final XmlElement _rawElement; - static final Map _elements = { - 'circle': (el) => new SvgCircle(el), - 'path': (el) => new SvgPath(el), + 'circle': (el) => new SvgCircle.fromXml(el), + 'path': (el) => new SvgPath.fromXml(el), + 'g': (el) => new SvgGroup.fromXml(el), + 'rect': (el) => new SvgRect.fromXml(el), + 'polygon': (el) => new SvgPolygon.fromXml(el), + 'title': (el) => const SvgNoop(), + 'desc': (el) => const SvgNoop(), }; - void draw(XmlElement element, Canvas canvas); + const SvgBaseElement(); - const SvgBaseElement._(this._rawElement); + void draw(Canvas canvas); factory SvgBaseElement.fromXml(XmlElement element) { final ret = _elements[element.name.local]; @@ -26,39 +30,135 @@ abstract class SvgBaseElement { return ret(element); } + + void _startTransform(Matrix4 transform, Canvas canvas) { + if (transform != null) { + canvas.save(); + canvas.transform(transform.storage); + } + } + + void _closeTransform(Matrix4 transform, Canvas canvas) { + if (transform != null) { + canvas.restore(); + } + } +} + +class SvgNoop extends SvgBaseElement { + const SvgNoop(); + + void draw(Canvas canvas) {} } class SvgCircle extends SvgBaseElement { - const SvgCircle(XmlElement el) : super._(el); + final double cx; + final double cy; + final double r; + final Color fill; + final Paint paint; - void draw(XmlElement el, Canvas canvas) { + const SvgCircle(this.cx, this.cy, this.r, this.fill, this.paint); + + factory SvgCircle.fromXml(XmlElement el) { final cx = double.parse(el.getAttribute('cx')); final cy = double.parse(el.getAttribute('cy')); final r = double.parse(el.getAttribute('r')); final fill = parseColor(el.getAttribute('fill')); final opacity = double.parse(el.getAttribute('opacity')); final paint = new Paint()..color = fill.withAlpha((255 * opacity).toInt()); + + return new SvgCircle(cx, cy, r, fill, paint); + } + + void draw(Canvas canvas) { canvas.drawCircle(new Offset(cx, cy), r, paint); } } +class SvgGroup extends SvgBaseElement { + final List children; + const SvgGroup(this.children); + + factory SvgGroup.fromXml(XmlElement el) { + var children = new List(); + el.children.forEach((child) { + if (child is XmlElement) { + children.add(new SvgBaseElement.fromXml(child)); + } + }); + return new SvgGroup( + children, + //TODO: when Dart2 is around use this + // el.children + // .whereType() + // .map((child) => new SvgBaseElement.fromXml(child)), + ); + } + + void draw(Canvas canvas) { + children.forEach((child) => child.draw(canvas)); + } +} + class SvgPath extends SvgBaseElement { - const SvgPath(XmlElement el) : super._(el); + final Path path; + final Paint paint; + final Matrix4 transform; + const SvgPath(this.path, this.paint, {this.transform}); - void draw(XmlElement el, Canvas canvas) { + factory SvgPath.fromXml(XmlElement el) { final d = el.getAttribute('d'); final p = Path.parseSvgPathData(d); final fill = parseColor(el.getAttribute('fill')); final paint = new Paint()..color = fill; - // TODO: Actually implement a parser for this - // Maybe take logic from https://github.com/flutter/flutter/blob/master/dev/tools/vitool/lib/vitool.dart - if (el.getAttribute('transform') != null) { - final m = new Matrix4.identity(); - m.scale(0.1); - p.transform(m.storage); - canvas.scale(.1, .1); - } - canvas.drawPath(p, paint); + final transform = parseTransform(el.getAttribute('transform')); + return new SvgPath(p, paint, transform: transform); + } + + void draw(Canvas canvas) { + _startTransform(transform, canvas); + canvas.drawPath(path, paint); + _closeTransform(transform, canvas); + } +} + +class SvgRect extends SvgBaseElement { + final Rect rect; + final Paint paint; + const SvgRect(this.rect, this.paint); + + factory SvgRect.fromXml(XmlElement el) { + final x = double.parse(el.getAttribute('x')); + final y = double.parse(el.getAttribute('y')); + final w = double.parse(el.getAttribute('width')); + final h = double.parse(el.getAttribute('height')); + + final paint = new Paint()..color = parseColor(el.getAttribute('fill')); + return new SvgRect(new Rect.fromLTWH(x, y, w, h), paint); + } + + void draw(Canvas canvas) { + canvas.drawRect(rect, paint); + } +} + +class SvgPolygon extends SvgBaseElement { + final Float32List points; + final Paint paint; + + const SvgPolygon(this.points, this.paint); + + factory SvgPolygon.fromXml(XmlElement el) { + final points = parsePoints(el.getAttribute('points')); + final paint = new Paint() + ..color = parseColor(el.getAttribute('fill')) + ..style = PaintingStyle.fill; + return new SvgPolygon(points, paint); + } + + void draw(Canvas canvas) { + canvas.drawRawPoints(PointMode.polygon, points, paint); } } diff --git a/third_party/lib/src/parsers.dart b/third_party/lib/src/parsers.dart index 6287c33a4704..6dbfa46722dc 100644 --- a/third_party/lib/src/parsers.dart +++ b/third_party/lib/src/parsers.dart @@ -1,4 +1,8 @@ import 'dart:ui'; +import 'dart:typed_data'; +import 'dart:math'; + +import 'package:vector_math/vector_math_64.dart'; Rect parseViewBox(String viewbox) { if (viewbox == null || viewbox == '') { @@ -11,6 +15,9 @@ Rect parseViewBox(String viewbox) { } Color parseColor(String colorString) { + if (colorString == null || colorString.length == 0) { + return const Color.fromARGB(255, 0, 0, 0); + } if (colorString[0] == '#') { if (colorString.length == 4) { final r = colorString[1]; @@ -33,3 +40,84 @@ Color parseColor(String colorString) { throw new ArgumentError.value( colorString, "colorString", "Unknown color $colorString"); } + +// TODO: is this better off using custom parsing logic vs regex? +final _spaceOrCommaRegEx = new RegExp(' |,'); +Float32List parsePoints(String points) { + if (points == null || points.length == 0) { + return null; + } + + return new Float32List.fromList(points + .trim() + .split(_spaceOrCommaRegEx) + .map((pt) => double.parse(pt)) + .toList()); +} + +const String _transformCommandAtom = ' *([^(]+)\\(([^)]*)\\)'; +final RegExp _transformValidator = new RegExp('^($_transformCommandAtom)*\$'); +final RegExp _transformCommand = new RegExp(_transformCommandAtom); + +Matrix4 parseTransform(String transform) { + if (transform == null) { + return null; + } + + if (!_transformValidator.hasMatch(transform)) + throw new Exception('illegal or unsupported transform: $transform'); + final Iterable matches = + _transformCommand.allMatches(transform).toList().reversed; + Matrix4 result = new Matrix4.identity(); + for (Match m in matches) { + final String command = m.group(1); + final String params = m.group(2); + + if (command == 'translate') { + result = _parseSvgTranslate(params).multiplied(result); + continue; + } + if (command == 'scale') { + result = _parseSvgScale(params).multiplied(result); + continue; + } + if (command == 'rotate') { + result = _parseSvgRotate(params).multiplied(result); + continue; + } + throw new Exception('unimplemented transform: $command'); + } + return result; +} + +final RegExp _valueSeparator = new RegExp('( *, *| +)'); + +Matrix4 _parseSvgTranslate(String paramsStr) { + final List params = paramsStr.split(_valueSeparator); + assert(params.isNotEmpty); + assert(params.length <= 2); + final double x = double.parse(params[0]); + final double y = params.length < 2 ? x : double.parse(params[1]); + return _matrix(1.0, 0.0, 0.0, 1.0, x, y); +} + +Matrix4 _parseSvgScale(String paramsStr) { + final List params = paramsStr.split(_valueSeparator); + assert(params.isNotEmpty); + assert(params.length <= 2); + final double x = double.parse(params[0]); + final double y = params.length < 2 ? x : double.parse(params[1]); + return _matrix(x, 0.0, 0.0, y, 0.0, 0.0); +} + +Matrix4 _parseSvgRotate(String paramsStr) { + final List params = paramsStr.split(_valueSeparator); + assert(params.length == 1); + final double a = radians(double.parse(params[0])); + return _matrix(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0); +} + +Matrix4 _matrix(double a, double b, double c, double d, double e, double f) { + return new Matrix4( + a, b, 0.0, 0.0, c, d, 0.0, 0.0, e, f, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); +} diff --git a/third_party/lib/src/paths.dart b/third_party/lib/src/paths.dart deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/third_party/lib/src/svg.dart b/third_party/lib/src/svg.dart index 070e7633fe5d..59731a863ba3 100644 --- a/third_party/lib/src/svg.dart +++ b/third_party/lib/src/svg.dart @@ -12,14 +12,15 @@ class SvgPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { if (_rawSvg == null) return; - var viewBox = - (_rawSvg.root.firstChild as XmlElement).getAttribute('viewBox'); + + var viewBox = _rawSvg.rootElement.getAttribute('viewBox'); final vbRect = parseViewBox(viewBox); - canvas.scale(size.width / vbRect.size.width, size.height / vbRect.size.height); - for (var el in _rawSvg.root.firstChild.children) { + canvas.scale( + size.width / vbRect.size.width, size.height / vbRect.size.height); + for (var el in _rawSvg.rootElement.children) { if (el is! XmlElement) continue; final svgEl = new SvgBaseElement.fromXml(el); - svgEl.draw(el, canvas); + svgEl.draw(canvas); } } diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index eb7974b4f8a2..681b268eb471 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -31,6 +31,16 @@ flutter: assets: - assets/alphachannel.svg - assets/aa.svg + - assets/deborah_ufw/new-action-expander.svg + - assets/deborah_ufw/new-camera.svg + - assets/deborah_ufw/new-gif-button.svg + - assets/deborah_ufw/new-gif.svg + - assets/deborah_ufw/new-image.svg + - assets/deborah_ufw/new-mention.svg + - assets/deborah_ufw/new-pause-button.svg + - assets/deborah_ufw/new-play-button.svg + - assets/deborah_ufw/new-send-circle.svg + - assets/deborah_ufw/numeric_25.svg # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg From 10e5569c87076cf67c78dc44c0ca0629f502cc79 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 12 Mar 2018 10:56:11 -0400 Subject: [PATCH 003/512] add ellipse --- third_party/assets/simple/ellipse.svg | 5 ++++ third_party/assets/{ => w3samples}/aa.svg | 0 .../assets/{ => w3samples}/alphachannel.svg | 0 third_party/lib/main.dart | 5 ++-- third_party/lib/src/elements.dart | 30 +++++++++++++++++-- third_party/pubspec.yaml | 5 ++-- 6 files changed, 38 insertions(+), 7 deletions(-) create mode 100644 third_party/assets/simple/ellipse.svg rename third_party/assets/{ => w3samples}/aa.svg (100%) rename third_party/assets/{ => w3samples}/alphachannel.svg (100%) diff --git a/third_party/assets/simple/ellipse.svg b/third_party/assets/simple/ellipse.svg new file mode 100644 index 000000000000..73e020c85638 --- /dev/null +++ b/third_party/assets/simple/ellipse.svg @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/third_party/assets/aa.svg b/third_party/assets/w3samples/aa.svg similarity index 100% rename from third_party/assets/aa.svg rename to third_party/assets/w3samples/aa.svg diff --git a/third_party/assets/alphachannel.svg b/third_party/assets/w3samples/alphachannel.svg similarity index 100% rename from third_party/assets/alphachannel.svg rename to third_party/assets/w3samples/alphachannel.svg diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 9cc02fa86213..57e999692855 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -7,8 +7,8 @@ import 'package:xml/xml.dart'; import 'package:flutter_svg/svg.dart'; const List assetNames = const [ - 'assets/aa.svg', - 'assets/alphachannel.svg', + 'assets/w3samples/aa.svg', + 'assets/w3samples/alphachannel.svg', 'assets/deborah_ufw/new-action-expander.svg', 'assets/deborah_ufw/new-camera.svg', 'assets/deborah_ufw/new-gif-button.svg', @@ -19,6 +19,7 @@ const List assetNames = const [ 'assets/deborah_ufw/new-play-button.svg', 'assets/deborah_ufw/new-send-circle.svg', 'assets/deborah_ufw/numeric_25.svg', + 'assets/simple/ellipse.svg', ]; void main() => runApp(new MyApp()); diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index aa36fa90332f..9d9af53d1480 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -14,6 +14,7 @@ abstract class SvgBaseElement { 'g': (el) => new SvgGroup.fromXml(el), 'rect': (el) => new SvgRect.fromXml(el), 'polygon': (el) => new SvgPolygon.fromXml(el), + 'ellipse': (el) => new SvgEllipse.fromXml(el), 'title': (el) => const SvgNoop(), 'desc': (el) => const SvgNoop(), }; @@ -55,10 +56,9 @@ class SvgCircle extends SvgBaseElement { final double cx; final double cy; final double r; - final Color fill; final Paint paint; - const SvgCircle(this.cx, this.cy, this.r, this.fill, this.paint); + const SvgCircle(this.cx, this.cy, this.r, this.paint); factory SvgCircle.fromXml(XmlElement el) { final cx = double.parse(el.getAttribute('cx')); @@ -68,7 +68,7 @@ class SvgCircle extends SvgBaseElement { final opacity = double.parse(el.getAttribute('opacity')); final paint = new Paint()..color = fill.withAlpha((255 * opacity).toInt()); - return new SvgCircle(cx, cy, r, fill, paint); + return new SvgCircle(cx, cy, r, paint); } void draw(Canvas canvas) { @@ -162,3 +162,27 @@ class SvgPolygon extends SvgBaseElement { canvas.drawRawPoints(PointMode.polygon, points, paint); } } + +class SvgEllipse extends SvgBaseElement { + final Rect boundingRect; + final Paint paint; + + const SvgEllipse(this.boundingRect, this.paint); + + factory SvgEllipse.fromXml(XmlElement el) { + final cx = double.parse(el.getAttribute('cx')); + final cy = double.parse(el.getAttribute('cy')); + final rx = double.parse(el.getAttribute('rx')); + final ry = double.parse(el.getAttribute('ry')); + final fill = parseColor(el.getAttribute('fill')); + //final opacity = double.parse(el.getAttribute('opacity')); + final paint = new Paint()..color = fill; //.withAlpha((255 * opacity).toInt()); + + Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); + return new SvgEllipse(r, paint); + } + + void draw(Canvas canvas) { + canvas.drawOval(boundingRect, paint); + } +} diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 681b268eb471..c3c907e09c43 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -29,8 +29,8 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - - assets/alphachannel.svg - - assets/aa.svg + - assets/w3samples/alphachannel.svg + - assets/w3samples/aa.svg - assets/deborah_ufw/new-action-expander.svg - assets/deborah_ufw/new-camera.svg - assets/deborah_ufw/new-gif-button.svg @@ -41,6 +41,7 @@ flutter: - assets/deborah_ufw/new-play-button.svg - assets/deborah_ufw/new-send-circle.svg - assets/deborah_ufw/numeric_25.svg + - assets/simple/ellipse.svg # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg From f72ccfcc135740517fafa21424971eb6fd4e370d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 12 Mar 2018 10:59:25 -0400 Subject: [PATCH 004/512] update readme --- third_party/lib/main.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 57e999692855..2ec631eac4ef 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -72,13 +72,13 @@ class _MyHomePageState extends State { title: new Text(widget.title), ), body: new GridView.extent( - maxCrossAxisExtent: 150.0, + maxCrossAxisExtent: 50.0, padding: const EdgeInsets.all(4.0), mainAxisSpacing: 4.0, crossAxisSpacing: 4.0, children: _painters.map((painter) { return new CustomPaint( - painter: painter, size: const Size(150.0, 150.0)); + painter: painter, size: const Size(50.0, 50.0)); }).toList(), ), ); From d8ee930b09687bb031bb1fbc57172f7b9c34af54 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 12 Mar 2018 14:43:06 -0400 Subject: [PATCH 005/512] better transform support, start refactoring widget --- third_party/assets/simple/ellipse.svg | 2 +- third_party/lib/main.dart | 17 ++-- third_party/lib/src/elements.dart | 86 +++++++++++++------ third_party/lib/src/parsers.dart | 78 +++++++++++++---- .../lib/src/{svg.dart => svg_painter.dart} | 0 third_party/lib/svg.dart | 18 +++- 6 files changed, 140 insertions(+), 61 deletions(-) rename third_party/lib/src/{svg.dart => svg_painter.dart} (100%) diff --git a/third_party/assets/simple/ellipse.svg b/third_party/assets/simple/ellipse.svg index 73e020c85638..b7d25b2b7c37 100644 --- a/third_party/assets/simple/ellipse.svg +++ b/third_party/assets/simple/ellipse.svg @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 2ec631eac4ef..684838b81a36 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -46,20 +46,16 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - List _painters = new List(); + List _painters = new List(); + final double _dimension = 50.0; @override void initState() { super.initState(); - // loadAsset('assets/deborah_ufw/new-camera.svg').then((xml) { - // setState(() { - // _svgDoc = xml; - // }); - // }); assetNames.forEach((assetName) { loadAsset(assetName).then((xml) { setState(() { - _painters.add(new SvgPainter(xml)); + _painters.add(new SvgImage(xml, new Size(_dimension, _dimension))); }); }); }); @@ -72,14 +68,11 @@ class _MyHomePageState extends State { title: new Text(widget.title), ), body: new GridView.extent( - maxCrossAxisExtent: 50.0, + maxCrossAxisExtent: _dimension, padding: const EdgeInsets.all(4.0), mainAxisSpacing: 4.0, crossAxisSpacing: 4.0, - children: _painters.map((painter) { - return new CustomPaint( - painter: painter, size: const Size(50.0, 50.0)); - }).toList(), + children: _painters.toList(), ), ); } diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index 9d9af53d1480..e989a0799903 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -1,4 +1,5 @@ import 'dart:ui'; +import 'package:meta/meta.dart'; import 'dart:typed_data'; import 'package:xml/xml.dart'; @@ -31,15 +32,29 @@ abstract class SvgBaseElement { return ret(element); } +} + +abstract class TransformableSvgElement extends SvgBaseElement { + final Matrix4 transform; + const TransformableSvgElement(this.transform); + + @override + void draw(Canvas canvas) { + _startTransform(canvas); + _innerDraw(canvas); + _closeTransform(canvas); + } + + void _innerDraw(Canvas canvas); - void _startTransform(Matrix4 transform, Canvas canvas) { + void _startTransform(Canvas canvas) { if (transform != null) { canvas.save(); canvas.transform(transform.storage); } } - void _closeTransform(Matrix4 transform, Canvas canvas) { + void _closeTransform(Canvas canvas) { if (transform != null) { canvas.restore(); } @@ -52,13 +67,13 @@ class SvgNoop extends SvgBaseElement { void draw(Canvas canvas) {} } -class SvgCircle extends SvgBaseElement { +class SvgCircle extends TransformableSvgElement { final double cx; final double cy; final double r; final Paint paint; - const SvgCircle(this.cx, this.cy, this.r, this.paint); + const SvgCircle(this.cx, this.cy, this.r, this.paint, Matrix4 transform) : super(transform); factory SvgCircle.fromXml(XmlElement el) { final cx = double.parse(el.getAttribute('cx')); @@ -67,18 +82,19 @@ class SvgCircle extends SvgBaseElement { final fill = parseColor(el.getAttribute('fill')); final opacity = double.parse(el.getAttribute('opacity')); final paint = new Paint()..color = fill.withAlpha((255 * opacity).toInt()); - - return new SvgCircle(cx, cy, r, paint); + final transform = parseTransform(el.getAttribute('transform')); + return new SvgCircle(cx, cy, r, paint, transform); } - void draw(Canvas canvas) { + @override + void _innerDraw(Canvas canvas) { canvas.drawCircle(new Offset(cx, cy), r, paint); } } -class SvgGroup extends SvgBaseElement { +class SvgGroup extends TransformableSvgElement { final List children; - const SvgGroup(this.children); + const SvgGroup(this.children, Matrix4 transform) : super(transform); factory SvgGroup.fromXml(XmlElement el) { var children = new List(); @@ -87,25 +103,31 @@ class SvgGroup extends SvgBaseElement { children.add(new SvgBaseElement.fromXml(child)); } }); + + final transform = parseTransform(el.getAttribute('transform')); + + return new SvgGroup( children, - //TODO: when Dart2 is around use this + //TODO: when Dart2 is around use this instead of above // el.children // .whereType() // .map((child) => new SvgBaseElement.fromXml(child)), + transform ); } - void draw(Canvas canvas) { + @override + void _innerDraw(Canvas canvas) { children.forEach((child) => child.draw(canvas)); } } -class SvgPath extends SvgBaseElement { +class SvgPath extends TransformableSvgElement { final Path path; final Paint paint; final Matrix4 transform; - const SvgPath(this.path, this.paint, {this.transform}); + const SvgPath(this.path, this.paint, {this.transform}) : super(transform); factory SvgPath.fromXml(XmlElement el) { final d = el.getAttribute('d'); @@ -117,17 +139,16 @@ class SvgPath extends SvgBaseElement { return new SvgPath(p, paint, transform: transform); } - void draw(Canvas canvas) { - _startTransform(transform, canvas); + @override + void _innerDraw(Canvas canvas) { canvas.drawPath(path, paint); - _closeTransform(transform, canvas); } } -class SvgRect extends SvgBaseElement { +class SvgRect extends TransformableSvgElement { final Rect rect; final Paint paint; - const SvgRect(this.rect, this.paint); + const SvgRect(this.rect, this.paint, Matrix4 transform) : super(transform); factory SvgRect.fromXml(XmlElement el) { final x = double.parse(el.getAttribute('x')); @@ -135,39 +156,45 @@ class SvgRect extends SvgBaseElement { final w = double.parse(el.getAttribute('width')); final h = double.parse(el.getAttribute('height')); + final transform = parseTransform(el.getAttribute('transform')); final paint = new Paint()..color = parseColor(el.getAttribute('fill')); - return new SvgRect(new Rect.fromLTWH(x, y, w, h), paint); + return new SvgRect(new Rect.fromLTWH(x, y, w, h), paint, transform); } - void draw(Canvas canvas) { + @override + void _innerDraw(Canvas canvas) { canvas.drawRect(rect, paint); } } -class SvgPolygon extends SvgBaseElement { +class SvgPolygon extends TransformableSvgElement { final Float32List points; final Paint paint; - const SvgPolygon(this.points, this.paint); + const SvgPolygon(this.points, this.paint, Matrix4 transform) : super(transform); factory SvgPolygon.fromXml(XmlElement el) { final points = parsePoints(el.getAttribute('points')); final paint = new Paint() ..color = parseColor(el.getAttribute('fill')) ..style = PaintingStyle.fill; - return new SvgPolygon(points, paint); + + + final transform = parseTransform(el.getAttribute('transform')); + return new SvgPolygon(points, paint, transform); } - void draw(Canvas canvas) { + @override + void _innerDraw(Canvas canvas) { canvas.drawRawPoints(PointMode.polygon, points, paint); } } -class SvgEllipse extends SvgBaseElement { +class SvgEllipse extends TransformableSvgElement { final Rect boundingRect; final Paint paint; - const SvgEllipse(this.boundingRect, this.paint); + const SvgEllipse(this.boundingRect, this.paint, Matrix4 transform) : super(transform); factory SvgEllipse.fromXml(XmlElement el) { final cx = double.parse(el.getAttribute('cx')); @@ -179,10 +206,13 @@ class SvgEllipse extends SvgBaseElement { final paint = new Paint()..color = fill; //.withAlpha((255 * opacity).toInt()); Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); - return new SvgEllipse(r, paint); + + final transform = parseTransform(el.getAttribute('transform')); + return new SvgEllipse(r, paint, transform); } - void draw(Canvas canvas) { + @override + void _innerDraw(Canvas canvas) { canvas.drawOval(boundingRect, paint); } } diff --git a/third_party/lib/src/parsers.dart b/third_party/lib/src/parsers.dart index 6dbfa46722dc..d87b628e3dea 100644 --- a/third_party/lib/src/parsers.dart +++ b/third_party/lib/src/parsers.dart @@ -59,6 +59,17 @@ const String _transformCommandAtom = ' *([^(]+)\\(([^)]*)\\)'; final RegExp _transformValidator = new RegExp('^($_transformCommandAtom)*\$'); final RegExp _transformCommand = new RegExp(_transformCommandAtom); +typedef Matrix4 MatrixParser(String paramsStr, Matrix4 current); + +const Map _matrixParsers = const { + 'matrix': _parseSvgMatrix, + 'translate': _parseSvgTranslate, + 'scale': _parseSvgScale, + 'rotate': _parseSvgRotate, + 'skewX': _parseSvgSkewX, + 'skewY': _parseSvgSkewY, +}; + Matrix4 parseTransform(String transform) { if (transform == null) { return null; @@ -73,48 +84,77 @@ Matrix4 parseTransform(String transform) { final String command = m.group(1); final String params = m.group(2); - if (command == 'translate') { - result = _parseSvgTranslate(params).multiplied(result); - continue; - } - if (command == 'scale') { - result = _parseSvgScale(params).multiplied(result); - continue; - } - if (command == 'rotate') { - result = _parseSvgRotate(params).multiplied(result); - continue; + final transformer = _matrixParsers[command]; + if (transformer == null) { + throw new FormatException('Unsupported transform: $command'); } - throw new Exception('unimplemented transform: $command'); + + result = transformer(params, result); } return result; } final RegExp _valueSeparator = new RegExp('( *, *| +)'); -Matrix4 _parseSvgTranslate(String paramsStr) { +Matrix4 _parseSvgMatrix(String paramsStr, Matrix4 current) { + final params = paramsStr.split(_valueSeparator); + assert(params.isNotEmpty); + assert(params.length == 6); + final a = double.parse(params[0]); + final b = double.parse(params[1]); + final c = double.parse(params[2]); + final d = double.parse(params[3]); + final e = double.parse(params[4]); + final f = double.parse(params[5]); + + return _matrix(a, b, c, d, e, f).multiplied(current); +} + +Matrix4 _parseSvgSkewX(String paramsStr, Matrix4 current) { + final x = double.parse(paramsStr); + return _matrix(1.0, tan(x), 0.0, 0.0, 1.0, 0.0).multiplied(current); +} + +Matrix4 _parseSvgSkewY(String paramsStr, Matrix4 current) { + final y = double.parse(paramsStr); + return _matrix(1.0, 0.0, 0.0, tan(y), 1.0, 0.0).multiplied(current); +} + +Matrix4 _parseSvgTranslate(String paramsStr, Matrix4 current) { final List params = paramsStr.split(_valueSeparator); assert(params.isNotEmpty); assert(params.length <= 2); final double x = double.parse(params[0]); final double y = params.length < 2 ? x : double.parse(params[1]); - return _matrix(1.0, 0.0, 0.0, 1.0, x, y); + return _matrix(1.0, 0.0, 0.0, 1.0, x, y).multiplied(current); } -Matrix4 _parseSvgScale(String paramsStr) { +Matrix4 _parseSvgScale(String paramsStr, Matrix4 current) { final List params = paramsStr.split(_valueSeparator); assert(params.isNotEmpty); assert(params.length <= 2); final double x = double.parse(params[0]); final double y = params.length < 2 ? x : double.parse(params[1]); - return _matrix(x, 0.0, 0.0, y, 0.0, 0.0); + return _matrix(x, 0.0, 0.0, y, 0.0, 0.0).multiplied(current); } -Matrix4 _parseSvgRotate(String paramsStr) { +Matrix4 _parseSvgRotate(String paramsStr, Matrix4 current) { final List params = paramsStr.split(_valueSeparator); - assert(params.length == 1); + assert(params.length <= 3); final double a = radians(double.parse(params[0])); - return _matrix(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0); + + final rotate = _matrix(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0); + + if (params.length > 1) { + final double x = double.parse(params[1]); + final double y = params.length == 3 ? double.parse(params[2]) : x; + return _matrix(1.0, 0.0, 0.0, 1.0, x, y) + .multiplied(current) + .multiplied(rotate) + .multiplied(_matrix(1.0, 0.0, 0.0, 1.0, -x, -y)); + } else { + return rotate.multiplied(current); + } } Matrix4 _matrix(double a, double b, double c, double d, double e, double f) { diff --git a/third_party/lib/src/svg.dart b/third_party/lib/src/svg_painter.dart similarity index 100% rename from third_party/lib/src/svg.dart rename to third_party/lib/src/svg_painter.dart diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 5eec5703cab1..2c8ea7ea82df 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -1 +1,17 @@ -export 'package:flutter_svg/src/svg.dart'; +import 'dart:ui'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/src/svg_painter.dart'; +import 'package:xml/xml.dart'; + + +class SvgImage extends StatelessWidget { + final Size size; + final XmlDocument _rawSvg; + + const SvgImage(this._rawSvg, this.size, {Key key}) : super(key: key); + + Widget build(BuildContext context) { + return new CustomPaint( + painter: new SvgPainter(_rawSvg), size: size); + } +} From 221e0e3b0b6bbca7216e41ef587faaad786b16ca Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 12 Mar 2018 15:01:24 -0400 Subject: [PATCH 006/512] fix polygon, add polyline --- third_party/lib/src/elements.dart | 37 ++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index e989a0799903..79a81394389c 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -15,6 +15,7 @@ abstract class SvgBaseElement { 'g': (el) => new SvgGroup.fromXml(el), 'rect': (el) => new SvgRect.fromXml(el), 'polygon': (el) => new SvgPolygon.fromXml(el), + 'polyline': (el) => new SvgPolyline.fromXml(el), 'ellipse': (el) => new SvgEllipse.fromXml(el), 'title': (el) => const SvgNoop(), 'desc': (el) => const SvgNoop(), @@ -168,28 +169,54 @@ class SvgRect extends TransformableSvgElement { } class SvgPolygon extends TransformableSvgElement { - final Float32List points; + final Path path; final Paint paint; - const SvgPolygon(this.points, this.paint, Matrix4 transform) : super(transform); + const SvgPolygon(this.path, this.paint, Matrix4 transform) : super(transform); factory SvgPolygon.fromXml(XmlElement el) { - final points = parsePoints(el.getAttribute('points')); + // flutter draws polygons without filling them. Convert to path. + final path = Path.parseSvgPathData('M' + el.getAttribute('points') + 'z'); final paint = new Paint() ..color = parseColor(el.getAttribute('fill')) ..style = PaintingStyle.fill; final transform = parseTransform(el.getAttribute('transform')); - return new SvgPolygon(points, paint, transform); + return new SvgPolygon(path, paint, transform); } @override void _innerDraw(Canvas canvas) { - canvas.drawRawPoints(PointMode.polygon, points, paint); + //canvas.drawRawPoints(PointMode.polygon, points, paint); + canvas.drawPath(path, paint); } } +class SvgPolyline extends TransformableSvgElement { + final Path path; + final Paint paint; + + const SvgPolyline(this.path, this.paint, Matrix4 transform) : super(transform); + + factory SvgPolyline.fromXml(XmlElement el) { + // flutter draws polygons without filling them. Convert to path. + final path = Path.parseSvgPathData('M' + el.getAttribute('points')); + final paint = new Paint() + ..color = parseColor(el.getAttribute('fill')) + ..style = PaintingStyle.fill; + + + final transform = parseTransform(el.getAttribute('transform')); + return new SvgPolyline(path, paint, transform); + } + + @override + void _innerDraw(Canvas canvas) { + //canvas.drawRawPoints(PointMode.polygon, points, paint); + canvas.drawPath(path, paint); + } +} class SvgEllipse extends TransformableSvgElement { final Rect boundingRect; final Paint paint; From 4a3a1333aff26dedb038680fe56496b542f7c67d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 12 Mar 2018 16:51:42 -0400 Subject: [PATCH 007/512] start making room for better async support for loading --- third_party/lib/main.dart | 15 +++------------ third_party/lib/svg.dart | 33 ++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 684838b81a36..6cc407b11934 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart' show rootBundle; import 'package:xml/xml.dart'; import 'package:flutter_svg/svg.dart'; @@ -47,17 +46,14 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { List _painters = new List(); - final double _dimension = 50.0; + final double _dimension = 350.0; @override void initState() { super.initState(); assetNames.forEach((assetName) { - loadAsset(assetName).then((xml) { - setState(() { - _painters.add(new SvgImage(xml, new Size(_dimension, _dimension))); - }); - }); + _painters + .add(new SvgImage.fromAsset(assetName, new Size(_dimension, _dimension))); }); } @@ -77,8 +73,3 @@ class _MyHomePageState extends State { ); } } - -Future loadAsset(String assetName) async { - final xml = await rootBundle.loadString(assetName); - return parse(xml); -} diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 2c8ea7ea82df..fefaf557dc70 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -1,17 +1,40 @@ import 'dart:ui'; +import 'dart:async'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/src/svg_painter.dart'; -import 'package:xml/xml.dart'; +import 'package:flutter/services.dart' show rootBundle; +import 'package:xml/xml.dart'; class SvgImage extends StatelessWidget { final Size size; - final XmlDocument _rawSvg; + final Future future; + + const SvgImage._(this.future, this.size, {Key key}) : super(key: key); - const SvgImage(this._rawSvg, this.size, {Key key}) : super(key: key); + factory SvgImage.fromAsset(String assetName, Size size, {Key key}) { + return new SvgImage._( + loadAsset(assetName), + size, + key: key, + ); + } Widget build(BuildContext context) { - return new CustomPaint( - painter: new SvgPainter(_rawSvg), size: size); + return new FutureBuilder( + future: future, + builder: ((context, snapShot) { + if (snapShot.hasData) { + return new CustomPaint( + painter: new SvgPainter(snapShot.data), size: size); + } + return new LimitedBox(); + }), + ); } } + +Future loadAsset(String assetName) async { + final xml = await rootBundle.loadString(assetName); + return parse(xml); +} From eb719a6f754175cd88d52b64796c0bc05a62edc5 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 13 Mar 2018 14:32:34 -0400 Subject: [PATCH 008/512] refactor parsers, better support for fill and stroke, still wip on that --- third_party/lib/main.dart | 33 +++- third_party/lib/src/elements.dart | 78 +++++--- third_party/lib/src/parsers/colors.dart | 186 ++++++++++++++++++ .../lib/src/{ => parsers}/parsers.dart | 41 ---- third_party/lib/src/parsers/xml_parsers.dart | 47 +++++ third_party/lib/src/svg_painter.dart | 2 +- third_party/lib/svg.dart | 13 +- 7 files changed, 317 insertions(+), 83 deletions(-) create mode 100644 third_party/lib/src/parsers/colors.dart rename third_party/lib/src/{ => parsers}/parsers.dart (78%) create mode 100644 third_party/lib/src/parsers/xml_parsers.dart diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 6cc407b11934..917c88af3685 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -46,14 +46,17 @@ class MyHomePage extends StatefulWidget { class _MyHomePageState extends State { List _painters = new List(); - final double _dimension = 350.0; + double _dimension; @override void initState() { super.initState(); + _dimension = 350.0; assetNames.forEach((assetName) { - _painters - .add(new SvgImage.fromAsset(assetName, new Size(_dimension, _dimension))); + _painters.add(new SvgImage.fromAsset( + assetName, + new Size(_dimension, _dimension), + )); }); } @@ -63,13 +66,23 @@ class _MyHomePageState extends State { appBar: new AppBar( title: new Text(widget.title), ), - body: new GridView.extent( - maxCrossAxisExtent: _dimension, - padding: const EdgeInsets.all(4.0), - mainAxisSpacing: 4.0, - crossAxisSpacing: 4.0, - children: _painters.toList(), - ), + body: new Column(children: [ + new Slider( + min: 1.0, + max: MediaQuery.of(context).size.width - 10.0, + value: _dimension, + onChanged: (val) => setState(() => _dimension = val)), + new Expanded( + child: new GridView.extent( + shrinkWrap: true, + maxCrossAxisExtent: _dimension, + padding: const EdgeInsets.all(4.0), + mainAxisSpacing: 4.0, + crossAxisSpacing: 4.0, + children: _painters.toList(), + ), + ), + ]), ); } } diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index 79a81394389c..c73316ac3e9c 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -1,10 +1,9 @@ import 'dart:ui'; -import 'package:meta/meta.dart'; -import 'dart:typed_data'; import 'package:xml/xml.dart'; import 'package:vector_math/vector_math_64.dart'; -import 'parsers.dart'; +import 'parsers/parsers.dart'; +import 'parsers/xml_parsers.dart'; typedef SvgBaseElement SvgElementFactory(XmlElement el); @@ -17,6 +16,7 @@ abstract class SvgBaseElement { 'polygon': (el) => new SvgPolygon.fromXml(el), 'polyline': (el) => new SvgPolyline.fromXml(el), 'ellipse': (el) => new SvgEllipse.fromXml(el), + 'line': (el) => new SvgLine.fromXml(el), 'title': (el) => const SvgNoop(), 'desc': (el) => const SvgNoop(), }; @@ -74,15 +74,14 @@ class SvgCircle extends TransformableSvgElement { final double r; final Paint paint; - const SvgCircle(this.cx, this.cy, this.r, this.paint, Matrix4 transform) : super(transform); + const SvgCircle(this.cx, this.cy, this.r, this.paint, Matrix4 transform) + : super(transform); factory SvgCircle.fromXml(XmlElement el) { final cx = double.parse(el.getAttribute('cx')); final cy = double.parse(el.getAttribute('cy')); final r = double.parse(el.getAttribute('r')); - final fill = parseColor(el.getAttribute('fill')); - final opacity = double.parse(el.getAttribute('opacity')); - final paint = new Paint()..color = fill.withAlpha((255 * opacity).toInt()); + final paint = parseFill(el); final transform = parseTransform(el.getAttribute('transform')); return new SvgCircle(cx, cy, r, paint, transform); } @@ -107,15 +106,13 @@ class SvgGroup extends TransformableSvgElement { final transform = parseTransform(el.getAttribute('transform')); - return new SvgGroup( - children, - //TODO: when Dart2 is around use this instead of above - // el.children - // .whereType() - // .map((child) => new SvgBaseElement.fromXml(child)), - transform - ); + children, + //TODO: when Dart2 is around use this instead of above + // el.children + // .whereType() + // .map((child) => new SvgBaseElement.fromXml(child)), + transform); } @override @@ -133,8 +130,7 @@ class SvgPath extends TransformableSvgElement { factory SvgPath.fromXml(XmlElement el) { final d = el.getAttribute('d'); final p = Path.parseSvgPathData(d); - final fill = parseColor(el.getAttribute('fill')); - final paint = new Paint()..color = fill; + final paint = parseFill(el); final transform = parseTransform(el.getAttribute('transform')); return new SvgPath(p, paint, transform: transform); @@ -158,7 +154,7 @@ class SvgRect extends TransformableSvgElement { final h = double.parse(el.getAttribute('height')); final transform = parseTransform(el.getAttribute('transform')); - final paint = new Paint()..color = parseColor(el.getAttribute('fill')); + final paint = parseFill(el); return new SvgRect(new Rect.fromLTWH(x, y, w, h), paint, transform); } @@ -177,10 +173,8 @@ class SvgPolygon extends TransformableSvgElement { factory SvgPolygon.fromXml(XmlElement el) { // flutter draws polygons without filling them. Convert to path. final path = Path.parseSvgPathData('M' + el.getAttribute('points') + 'z'); - final paint = new Paint() - ..color = parseColor(el.getAttribute('fill')) - ..style = PaintingStyle.fill; + final paint = parseFill(el); final transform = parseTransform(el.getAttribute('transform')); return new SvgPolygon(path, paint, transform); @@ -197,15 +191,13 @@ class SvgPolyline extends TransformableSvgElement { final Path path; final Paint paint; - const SvgPolyline(this.path, this.paint, Matrix4 transform) : super(transform); + const SvgPolyline(this.path, this.paint, Matrix4 transform) + : super(transform); factory SvgPolyline.fromXml(XmlElement el) { // flutter draws polygons without filling them. Convert to path. final path = Path.parseSvgPathData('M' + el.getAttribute('points')); - final paint = new Paint() - ..color = parseColor(el.getAttribute('fill')) - ..style = PaintingStyle.fill; - + final paint = parseFill(el); final transform = parseTransform(el.getAttribute('transform')); return new SvgPolyline(path, paint, transform); @@ -217,20 +209,20 @@ class SvgPolyline extends TransformableSvgElement { canvas.drawPath(path, paint); } } + class SvgEllipse extends TransformableSvgElement { final Rect boundingRect; final Paint paint; - const SvgEllipse(this.boundingRect, this.paint, Matrix4 transform) : super(transform); + const SvgEllipse(this.boundingRect, this.paint, Matrix4 transform) + : super(transform); factory SvgEllipse.fromXml(XmlElement el) { final cx = double.parse(el.getAttribute('cx')); final cy = double.parse(el.getAttribute('cy')); final rx = double.parse(el.getAttribute('rx')); final ry = double.parse(el.getAttribute('ry')); - final fill = parseColor(el.getAttribute('fill')); - //final opacity = double.parse(el.getAttribute('opacity')); - final paint = new Paint()..color = fill; //.withAlpha((255 * opacity).toInt()); + final paint = parseFill(el); Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); @@ -243,3 +235,29 @@ class SvgEllipse extends TransformableSvgElement { canvas.drawOval(boundingRect, paint); } } + +class SvgLine extends TransformableSvgElement { + final Offset start; + final Offset end; + final Paint paint; + + const SvgLine(this.start, this.end, this.paint, Matrix4 transform) + : super(transform); + + factory SvgLine.fromXml(XmlElement el) { + final x1 = double.parse(el.getAttribute('x1')); + final x2 = double.parse(el.getAttribute('x2')); + final y1 = double.parse(el.getAttribute('y1')); + final y2 = double.parse(el.getAttribute('y2')); + final paint = parseStroke(el); + + final transform = parseTransform(el.getAttribute('transform')); + return new SvgLine( + new Offset(x1, x2), new Offset(y1, y2), paint, transform); + } + + @override + void _innerDraw(Canvas canvas) { + canvas.drawLine(start, end, paint); + } +} diff --git a/third_party/lib/src/parsers/colors.dart b/third_party/lib/src/parsers/colors.dart new file mode 100644 index 000000000000..129d5d0cb41d --- /dev/null +++ b/third_party/lib/src/parsers/colors.dart @@ -0,0 +1,186 @@ +import 'dart:ui'; + +const colorBlack = const Color.fromARGB(255, 0, 0, 0); + +Color parseColor(String colorString) { + if (colorString == null || colorString.length == 0) { + return const Color.fromARGB(255, 0, 0, 0); + } + if (colorString[0] == '#') { + if (colorString.length == 4) { + final r = colorString[1]; + final g = colorString[2]; + final b = colorString[3]; + colorString = '#$r$r$g$g$b$b'; + } + int color = int.parse(colorString.substring(1), + radix: 16, onError: (source) => null); + + if (colorString.length == 7) { + return new Color(color |= 0x00000000ff000000); + } + + if (colorString.length == 9) { + return new Color(color); + } + } + + final namedColor = _namedColors[colorString]; + if (namedColor != null) { + return namedColor; + } + + throw new ArgumentError.value( + colorString, "colorString", "Unknown color $colorString"); +} + +// https://www.w3.org/TR/SVG11/types.html#ColorKeywords +const Map _namedColors = const { + 'aliceblue': const Color.fromARGB(255, 240, 248, 255), + 'antiquewhite': const Color.fromARGB(255, 250, 235, 215), + 'aqua': const Color.fromARGB(255, 0, 255, 255), + 'aquamarine': const Color.fromARGB(255, 127, 255, 212), + 'azure': const Color.fromARGB(255, 240, 255, 255), + 'beige': const Color.fromARGB(255, 245, 245, 220), + 'bisque': const Color.fromARGB(255, 255, 228, 196), + 'black': const Color.fromARGB(255, 0, 0, 0), + 'blanchedalmond': const Color.fromARGB(255, 255, 235, 205), + 'blue': const Color.fromARGB(255, 0, 0, 255), + 'blueviolet': const Color.fromARGB(255, 138, 43, 226), + 'brown': const Color.fromARGB(255, 165, 42, 42), + 'burlywood': const Color.fromARGB(255, 222, 184, 135), + 'cadetblue': const Color.fromARGB(255, 95, 158, 160), + 'chartreuse': const Color.fromARGB(255, 127, 255, 0), + 'chocolate': const Color.fromARGB(255, 210, 105, 30), + 'coral': const Color.fromARGB(255, 255, 127, 80), + 'cornflowerblue': const Color.fromARGB(255, 100, 149, 237), + 'cornsilk': const Color.fromARGB(255, 255, 248, 220), + 'crimson': const Color.fromARGB(255, 220, 20, 60), + 'cyan': const Color.fromARGB(255, 0, 255, 255), + 'darkblue': const Color.fromARGB(255, 0, 0, 139), + 'darkcyan': const Color.fromARGB(255, 0, 139, 139), + 'darkgoldenrod': const Color.fromARGB(255, 184, 134, 11), + 'darkgray': const Color.fromARGB(255, 169, 169, 169), + 'darkgreen': const Color.fromARGB(255, 0, 100, 0), + 'darkgrey': const Color.fromARGB(255, 169, 169, 169), + 'darkkhaki': const Color.fromARGB(255, 189, 183, 107), + 'darkmagenta': const Color.fromARGB(255, 139, 0, 139), + 'darkolivegreen': const Color.fromARGB(255, 85, 107, 47), + 'darkorange': const Color.fromARGB(255, 255, 140, 0), + 'darkorchid': const Color.fromARGB(255, 153, 50, 204), + 'darkred': const Color.fromARGB(255, 139, 0, 0), + 'darksalmon': const Color.fromARGB(255, 233, 150, 122), + 'darkseagreen': const Color.fromARGB(255, 143, 188, 143), + 'darkslateblue': const Color.fromARGB(255, 72, 61, 139), + 'darkslategray': const Color.fromARGB(255, 47, 79, 79), + 'darkslategrey': const Color.fromARGB(255, 47, 79, 79), + 'darkturquoise': const Color.fromARGB(255, 0, 206, 209), + 'darkviolet': const Color.fromARGB(255, 148, 0, 211), + 'deeppink': const Color.fromARGB(255, 255, 20, 147), + 'deepskyblue': const Color.fromARGB(255, 0, 191, 255), + 'dimgray': const Color.fromARGB(255, 105, 105, 105), + 'dimgrey': const Color.fromARGB(255, 105, 105, 105), + 'dodgerblue': const Color.fromARGB(255, 30, 144, 255), + 'firebrick': const Color.fromARGB(255, 178, 34, 34), + 'floralwhite': const Color.fromARGB(255, 255, 250, 240), + 'forestgreen': const Color.fromARGB(255, 34, 139, 34), + 'fuchsia': const Color.fromARGB(255, 255, 0, 255), + 'gainsboro': const Color.fromARGB(255, 220, 220, 220), + 'ghostwhite': const Color.fromARGB(255, 248, 248, 255), + 'gold': const Color.fromARGB(255, 255, 215, 0), + 'goldenrod': const Color.fromARGB(255, 218, 165, 32), + 'gray': const Color.fromARGB(255, 128, 128, 128), + 'grey': const Color.fromARGB(255, 128, 128, 128), + 'green': const Color.fromARGB(255, 0, 128, 0), + 'greenyellow': const Color.fromARGB(255, 173, 255, 47), + 'honeydew': const Color.fromARGB(255, 240, 255, 240), + 'hotpink': const Color.fromARGB(255, 255, 105, 180), + 'indianred': const Color.fromARGB(255, 205, 92, 92), + 'indigo': const Color.fromARGB(255, 75, 0, 130), + 'ivory': const Color.fromARGB(255, 255, 255, 240), + 'khaki': const Color.fromARGB(255, 240, 230, 140), + 'lavender': const Color.fromARGB(255, 230, 230, 250), + 'lavenderblush': const Color.fromARGB(255, 255, 240, 245), + 'lawngreen': const Color.fromARGB(255, 124, 252, 0), + 'lemonchiffon': const Color.fromARGB(255, 255, 250, 205), + 'lightblue': const Color.fromARGB(255, 173, 216, 230), + 'lightcoral': const Color.fromARGB(255, 240, 128, 128), + 'lightcyan': const Color.fromARGB(255, 224, 255, 255), + 'lightgoldenrodyellow': const Color.fromARGB(255, 250, 250, 210), + 'lightgray': const Color.fromARGB(255, 211, 211, 211), + 'lightgreen': const Color.fromARGB(255, 144, 238, 144), + 'lightgrey': const Color.fromARGB(255, 211, 211, 211), + 'lightpink': const Color.fromARGB(255, 255, 182, 193), + 'lightsalmon': const Color.fromARGB(255, 255, 160, 122), + 'lightseagreen': const Color.fromARGB(255, 32, 178, 170), + 'lightskyblue': const Color.fromARGB(255, 135, 206, 250), + 'lightslategray': const Color.fromARGB(255, 119, 136, 153), + 'lightslategrey': const Color.fromARGB(255, 119, 136, 153), + 'lightsteelblue': const Color.fromARGB(255, 176, 196, 222), + 'lightyellow': const Color.fromARGB(255, 255, 255, 224), + 'lime': const Color.fromARGB(255, 0, 255, 0), + 'limegreen': const Color.fromARGB(255, 50, 205, 50), + 'linen': const Color.fromARGB(255, 250, 240, 230), + 'magenta': const Color.fromARGB(255, 255, 0, 255), + 'maroon': const Color.fromARGB(255, 128, 0, 0), + 'mediumaquamarine': const Color.fromARGB(255, 102, 205, 170), + 'mediumblue': const Color.fromARGB(255, 0, 0, 205), + 'mediumorchid': const Color.fromARGB(255, 186, 85, 211), + 'mediumpurple': const Color.fromARGB(255, 147, 112, 219), + 'mediumseagreen': const Color.fromARGB(255, 60, 179, 113), + 'mediumslateblue': const Color.fromARGB(255, 123, 104, 238), + 'mediumspringgreen': const Color.fromARGB(255, 0, 250, 154), + 'mediumturquoise': const Color.fromARGB(255, 72, 209, 204), + 'mediumvioletred': const Color.fromARGB(255, 199, 21, 133), + 'midnightblue': const Color.fromARGB(255, 25, 25, 112), + 'mintcream': const Color.fromARGB(255, 245, 255, 250), + 'mistyrose': const Color.fromARGB(255, 255, 228, 225), + 'moccasin': const Color.fromARGB(255, 255, 228, 181), + 'navajowhite': const Color.fromARGB(255, 255, 222, 173), + 'navy': const Color.fromARGB(255, 0, 0, 128), + 'oldlace': const Color.fromARGB(255, 253, 245, 230), + 'olive': const Color.fromARGB(255, 128, 128, 0), + 'olivedrab': const Color.fromARGB(255, 107, 142, 35), + 'orange': const Color.fromARGB(255, 255, 165, 0), + 'orangered': const Color.fromARGB(255, 255, 69, 0), + 'orchid': const Color.fromARGB(255, 218, 112, 214), + 'palegoldenrod': const Color.fromARGB(255, 238, 232, 170), + 'palegreen': const Color.fromARGB(255, 152, 251, 152), + 'paleturquoise': const Color.fromARGB(255, 175, 238, 238), + 'palevioletred': const Color.fromARGB(255, 219, 112, 147), + 'papayawhip': const Color.fromARGB(255, 255, 239, 213), + 'peachpuff': const Color.fromARGB(255, 255, 218, 185), + 'peru': const Color.fromARGB(255, 205, 133, 63), + 'pink': const Color.fromARGB(255, 255, 192, 203), + 'plum': const Color.fromARGB(255, 221, 160, 221), + 'powderblue': const Color.fromARGB(255, 176, 224, 230), + 'purple': const Color.fromARGB(255, 128, 0, 128), + 'red': const Color.fromARGB(255, 255, 0, 0), + 'rosybrown': const Color.fromARGB(255, 188, 143, 143), + 'royalblue': const Color.fromARGB(255, 65, 105, 225), + 'saddlebrown': const Color.fromARGB(255, 139, 69, 19), + 'salmon': const Color.fromARGB(255, 250, 128, 114), + 'sandybrown': const Color.fromARGB(255, 244, 164, 96), + 'seagreen': const Color.fromARGB(255, 46, 139, 87), + 'seashell': const Color.fromARGB(255, 255, 245, 238), + 'sienna': const Color.fromARGB(255, 160, 82, 45), + 'silver': const Color.fromARGB(255, 192, 192, 192), + 'skyblue': const Color.fromARGB(255, 135, 206, 235), + 'slateblue': const Color.fromARGB(255, 106, 90, 205), + 'slategray': const Color.fromARGB(255, 112, 128, 144), + 'slategrey': const Color.fromARGB(255, 112, 128, 144), + 'snow': const Color.fromARGB(255, 255, 250, 250), + 'springgreen': const Color.fromARGB(255, 0, 255, 127), + 'steelblue': const Color.fromARGB(255, 70, 130, 180), + 'tan': const Color.fromARGB(255, 210, 180, 140), + 'teal': const Color.fromARGB(255, 0, 128, 128), + 'thistle': const Color.fromARGB(255, 216, 191, 216), + 'tomato': const Color.fromARGB(255, 255, 99, 71), + 'turquoise': const Color.fromARGB(255, 64, 224, 208), + 'violet': const Color.fromARGB(255, 238, 130, 238), + 'wheat': const Color.fromARGB(255, 245, 222, 179), + 'white': const Color.fromARGB(255, 255, 255, 255), + 'whitesmoke': const Color.fromARGB(255, 245, 245, 245), + 'yellow': const Color.fromARGB(255, 255, 255, 0), + 'yellowgreen': const Color.fromARGB(255, 154, 205, 50), +}; diff --git a/third_party/lib/src/parsers.dart b/third_party/lib/src/parsers/parsers.dart similarity index 78% rename from third_party/lib/src/parsers.dart rename to third_party/lib/src/parsers/parsers.dart index d87b628e3dea..13c73968be16 100644 --- a/third_party/lib/src/parsers.dart +++ b/third_party/lib/src/parsers/parsers.dart @@ -14,47 +14,6 @@ Rect parseViewBox(String viewbox) { double.parse(parts[2]), double.parse(parts[3])); } -Color parseColor(String colorString) { - if (colorString == null || colorString.length == 0) { - return const Color.fromARGB(255, 0, 0, 0); - } - if (colorString[0] == '#') { - if (colorString.length == 4) { - final r = colorString[1]; - final g = colorString[2]; - final b = colorString[3]; - colorString = '#$r$r$g$g$b$b'; - } - int color = int.parse(colorString.substring(1), - radix: 16, onError: (source) => null); - - if (colorString.length == 7) { - return new Color(color |= 0x00000000ff000000); - } - - if (colorString.length == 9) { - return new Color(color); - } - } - - throw new ArgumentError.value( - colorString, "colorString", "Unknown color $colorString"); -} - -// TODO: is this better off using custom parsing logic vs regex? -final _spaceOrCommaRegEx = new RegExp(' |,'); -Float32List parsePoints(String points) { - if (points == null || points.length == 0) { - return null; - } - - return new Float32List.fromList(points - .trim() - .split(_spaceOrCommaRegEx) - .map((pt) => double.parse(pt)) - .toList()); -} - const String _transformCommandAtom = ' *([^(]+)\\(([^)]*)\\)'; final RegExp _transformValidator = new RegExp('^($_transformCommandAtom)*\$'); final RegExp _transformCommand = new RegExp(_transformCommandAtom); diff --git a/third_party/lib/src/parsers/xml_parsers.dart b/third_party/lib/src/parsers/xml_parsers.dart new file mode 100644 index 000000000000..98590ac4307f --- /dev/null +++ b/third_party/lib/src/parsers/xml_parsers.dart @@ -0,0 +1,47 @@ +import 'dart:ui'; + +import 'package:flutter_svg/src/parsers/colors.dart'; +import 'package:xml/xml.dart'; + +Paint parseStroke(XmlElement el) { + final rawStroke = el.getAttribute('stroke'); + if (rawStroke == null || rawStroke.length == 0) { + return new Paint()..color = colorBlack; + } + + var rawOpacity = el.getAttribute('stroke-opacity'); + if (rawOpacity == null) { + rawOpacity = el.getAttribute('opacity'); + } + final opacity = rawOpacity == null + ? 255 + : (double.parse(rawOpacity, (source) => 1.0).clamp(0.0, 1.0) * 255) + .toInt(); + final stroke = parseColor(rawStroke).withAlpha(opacity); + + // TODO: stroke types + return new Paint() + ..color = stroke + ..style = PaintingStyle.stroke; +} + +Paint parseFill(XmlElement el) { + final rawFill = el.getAttribute('fill'); + if (rawFill == null || rawFill.length == 0) { + return new Paint()..color = colorBlack; + } + + var rawOpacity = el.getAttribute('fill-opacity'); + if (rawOpacity == null) { + rawOpacity = el.getAttribute('opacity'); + } + final opacity = rawOpacity == null + ? 255 + : (double.parse(rawOpacity, (source) => 1.0).clamp(0.0, 1.0) * 255) + .toInt(); + final fill = parseColor(rawFill).withAlpha(opacity); + + return new Paint() + ..color = fill + ..style = PaintingStyle.fill; +} diff --git a/third_party/lib/src/svg_painter.dart b/third_party/lib/src/svg_painter.dart index 59731a863ba3..1c171aa3f25b 100644 --- a/third_party/lib/src/svg_painter.dart +++ b/third_party/lib/src/svg_painter.dart @@ -1,7 +1,7 @@ import 'package:xml/xml.dart'; import 'package:flutter/widgets.dart'; -import 'package:flutter_svg/src/parsers.dart'; +import 'package:flutter_svg/src/parsers/parsers.dart'; import 'package:flutter_svg/src/elements.dart'; class SvgPainter extends CustomPainter { diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index fefaf557dc70..7cc88133281a 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -1,4 +1,4 @@ -import 'dart:ui'; +import 'dart:ui' as ui; import 'dart:async'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/src/svg_painter.dart'; @@ -6,6 +6,17 @@ import 'package:flutter/services.dart' show rootBundle; import 'package:xml/xml.dart'; +Future createSvgImageFromAsset(String assetName, Size size) async { + final rawSvg = await loadAsset(assetName); + final ui.PictureRecorder recorder = new ui.PictureRecorder(); + final ui.Canvas canvas = new ui.Canvas(recorder); + final SvgPainter painter = new SvgPainter(rawSvg); + painter.paint(canvas, size); + return recorder + .endRecording() + .toImage(size.width.toInt(), size.height.toInt()); +} + class SvgImage extends StatelessWidget { final Size size; final Future future; From c704ea72c6baa536f341d97104f8097f92c639d6 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 13 Mar 2018 15:26:10 -0400 Subject: [PATCH 009/512] normalize stroke and fill handling --- third_party/lib/src/elements.dart | 94 ++++++++++---------- third_party/lib/src/parsers/xml_parsers.dart | 12 ++- third_party/lib/svg.dart | 11 --- 3 files changed, 57 insertions(+), 60 deletions(-) diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index c73316ac3e9c..588eb47b0445 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -21,7 +21,9 @@ abstract class SvgBaseElement { 'desc': (el) => const SvgNoop(), }; - const SvgBaseElement(); + final Paint stroke; + final Paint fill; + const SvgBaseElement(this.stroke, this.fill); void draw(Canvas canvas); @@ -37,7 +39,8 @@ abstract class SvgBaseElement { abstract class TransformableSvgElement extends SvgBaseElement { final Matrix4 transform; - const TransformableSvgElement(this.transform); + const TransformableSvgElement(this.transform, Paint stroke, Paint fill) + : super(stroke, fill); @override void draw(Canvas canvas) { @@ -63,38 +66,40 @@ abstract class TransformableSvgElement extends SvgBaseElement { } class SvgNoop extends SvgBaseElement { - const SvgNoop(); + const SvgNoop() : super(null, null); void draw(Canvas canvas) {} } class SvgCircle extends TransformableSvgElement { - final double cx; - final double cy; + final Offset center; final double r; - final Paint paint; - const SvgCircle(this.cx, this.cy, this.r, this.paint, Matrix4 transform) - : super(transform); + const SvgCircle( + this.center, this.r, Paint stroke, Paint fill, Matrix4 transform) + : super(transform, stroke, fill); factory SvgCircle.fromXml(XmlElement el) { final cx = double.parse(el.getAttribute('cx')); final cy = double.parse(el.getAttribute('cy')); final r = double.parse(el.getAttribute('r')); - final paint = parseFill(el); + final stroke = parseStroke(el); + final fill = parseFill(el); final transform = parseTransform(el.getAttribute('transform')); - return new SvgCircle(cx, cy, r, paint, transform); + return new SvgCircle(new Offset(cx, cy), r, stroke, fill, transform); } @override void _innerDraw(Canvas canvas) { - canvas.drawCircle(new Offset(cx, cy), r, paint); + if (stroke != null) canvas.drawCircle(center, r, stroke); + if (fill != null) canvas.drawCircle(center, r, fill); } } class SvgGroup extends TransformableSvgElement { final List children; - const SvgGroup(this.children, Matrix4 transform) : super(transform); + const SvgGroup(this.children, Matrix4 transform) + : super(transform, null, null); factory SvgGroup.fromXml(XmlElement el) { var children = new List(); @@ -123,29 +128,29 @@ class SvgGroup extends TransformableSvgElement { class SvgPath extends TransformableSvgElement { final Path path; - final Paint paint; final Matrix4 transform; - const SvgPath(this.path, this.paint, {this.transform}) : super(transform); + const SvgPath(this.path, Paint stroke, Paint fill, {this.transform}) + : super(transform, stroke, fill); factory SvgPath.fromXml(XmlElement el) { final d = el.getAttribute('d'); final p = Path.parseSvgPathData(d); - final paint = parseFill(el); final transform = parseTransform(el.getAttribute('transform')); - return new SvgPath(p, paint, transform: transform); + return new SvgPath(p, parseStroke(el), parseFill(el), transform: transform); } @override void _innerDraw(Canvas canvas) { - canvas.drawPath(path, paint); + if (stroke != null) canvas.drawPath(path, stroke); + if (fill != null) canvas.drawPath(path, fill); } } class SvgRect extends TransformableSvgElement { final Rect rect; - final Paint paint; - const SvgRect(this.rect, this.paint, Matrix4 transform) : super(transform); + const SvgRect(this.rect, Paint stroke, Paint fill, Matrix4 transform) + : super(transform, stroke, fill); factory SvgRect.fromXml(XmlElement el) { final x = double.parse(el.getAttribute('x')); @@ -154,95 +159,92 @@ class SvgRect extends TransformableSvgElement { final h = double.parse(el.getAttribute('height')); final transform = parseTransform(el.getAttribute('transform')); - final paint = parseFill(el); - return new SvgRect(new Rect.fromLTWH(x, y, w, h), paint, transform); + return new SvgRect(new Rect.fromLTWH(x, y, w, h), parseStroke(el), + parseFill(el), transform); } @override void _innerDraw(Canvas canvas) { - canvas.drawRect(rect, paint); + if (stroke != null) canvas.drawRect(rect, stroke); + if (fill != null) canvas.drawRect(rect, fill); } } class SvgPolygon extends TransformableSvgElement { final Path path; - final Paint paint; - const SvgPolygon(this.path, this.paint, Matrix4 transform) : super(transform); + const SvgPolygon(this.path, Paint stroke, Paint fill, Matrix4 transform) + : super(transform, stroke, fill); factory SvgPolygon.fromXml(XmlElement el) { // flutter draws polygons without filling them. Convert to path. final path = Path.parseSvgPathData('M' + el.getAttribute('points') + 'z'); - final paint = parseFill(el); - final transform = parseTransform(el.getAttribute('transform')); - return new SvgPolygon(path, paint, transform); + return new SvgPolygon(path, parseStroke(el), parseFill(el), transform); } @override void _innerDraw(Canvas canvas) { //canvas.drawRawPoints(PointMode.polygon, points, paint); - canvas.drawPath(path, paint); + if (stroke != null) canvas.drawPath(path, stroke); + if (fill != null) canvas.drawPath(path, fill); } } class SvgPolyline extends TransformableSvgElement { final Path path; - final Paint paint; - const SvgPolyline(this.path, this.paint, Matrix4 transform) - : super(transform); + const SvgPolyline(this.path, Paint stroke, Paint fill, Matrix4 transform) + : super(transform, stroke, fill); factory SvgPolyline.fromXml(XmlElement el) { // flutter draws polygons without filling them. Convert to path. final path = Path.parseSvgPathData('M' + el.getAttribute('points')); - final paint = parseFill(el); final transform = parseTransform(el.getAttribute('transform')); - return new SvgPolyline(path, paint, transform); + return new SvgPolyline(path, parseStroke(el), parseFill(el), transform); } @override void _innerDraw(Canvas canvas) { - //canvas.drawRawPoints(PointMode.polygon, points, paint); - canvas.drawPath(path, paint); + if (stroke != null) canvas.drawPath(path, stroke); + if (fill != null) canvas.drawPath(path, fill); } } class SvgEllipse extends TransformableSvgElement { final Rect boundingRect; - final Paint paint; - const SvgEllipse(this.boundingRect, this.paint, Matrix4 transform) - : super(transform); + const SvgEllipse( + this.boundingRect, Paint stroke, Paint fill, Matrix4 transform) + : super(transform, stroke, fill); factory SvgEllipse.fromXml(XmlElement el) { final cx = double.parse(el.getAttribute('cx')); final cy = double.parse(el.getAttribute('cy')); final rx = double.parse(el.getAttribute('rx')); final ry = double.parse(el.getAttribute('ry')); - final paint = parseFill(el); Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); final transform = parseTransform(el.getAttribute('transform')); - return new SvgEllipse(r, paint, transform); + return new SvgEllipse(r, parseStroke(el), parseFill(el), transform); } @override void _innerDraw(Canvas canvas) { - canvas.drawOval(boundingRect, paint); + if (stroke != null) canvas.drawOval(boundingRect, stroke); + if (fill != null) canvas.drawOval(boundingRect, fill); } } class SvgLine extends TransformableSvgElement { final Offset start; final Offset end; - final Paint paint; - const SvgLine(this.start, this.end, this.paint, Matrix4 transform) - : super(transform); + const SvgLine(this.start, this.end, Paint stroke, Matrix4 transform) + : super(transform, stroke, null); factory SvgLine.fromXml(XmlElement el) { final x1 = double.parse(el.getAttribute('x1')); @@ -250,7 +252,7 @@ class SvgLine extends TransformableSvgElement { final y1 = double.parse(el.getAttribute('y1')); final y2 = double.parse(el.getAttribute('y2')); final paint = parseStroke(el); - + final transform = parseTransform(el.getAttribute('transform')); return new SvgLine( new Offset(x1, x2), new Offset(y1, y2), paint, transform); @@ -258,6 +260,6 @@ class SvgLine extends TransformableSvgElement { @override void _innerDraw(Canvas canvas) { - canvas.drawLine(start, end, paint); + canvas.drawLine(start, end, stroke); } } diff --git a/third_party/lib/src/parsers/xml_parsers.dart b/third_party/lib/src/parsers/xml_parsers.dart index 98590ac4307f..f4a532152e37 100644 --- a/third_party/lib/src/parsers/xml_parsers.dart +++ b/third_party/lib/src/parsers/xml_parsers.dart @@ -6,7 +6,7 @@ import 'package:xml/xml.dart'; Paint parseStroke(XmlElement el) { final rawStroke = el.getAttribute('stroke'); if (rawStroke == null || rawStroke.length == 0) { - return new Paint()..color = colorBlack; + return null; } var rawOpacity = el.getAttribute('stroke-opacity'); @@ -25,10 +25,16 @@ Paint parseStroke(XmlElement el) { ..style = PaintingStyle.stroke; } -Paint parseFill(XmlElement el) { +Paint parseFill(XmlElement el, {bool isShape = true}) { final rawFill = el.getAttribute('fill'); if (rawFill == null || rawFill.length == 0) { - return new Paint()..color = colorBlack; + if (isShape) { + return new Paint() + ..color = colorBlack + ..style = PaintingStyle.fill; + } else { + return null; + } } var rawOpacity = el.getAttribute('fill-opacity'); diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 7cc88133281a..140862be8ed2 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -6,17 +6,6 @@ import 'package:flutter/services.dart' show rootBundle; import 'package:xml/xml.dart'; -Future createSvgImageFromAsset(String assetName, Size size) async { - final rawSvg = await loadAsset(assetName); - final ui.PictureRecorder recorder = new ui.PictureRecorder(); - final ui.Canvas canvas = new ui.Canvas(recorder); - final SvgPainter painter = new SvgPainter(rawSvg); - painter.paint(canvas, size); - return recorder - .endRecording() - .toImage(size.width.toInt(), size.height.toInt()); -} - class SvgImage extends StatelessWidget { final Size size; final Future future; From a5b91cf4846171d5bc4681dfca88ed2b04d34750 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 13 Mar 2018 16:03:07 -0400 Subject: [PATCH 010/512] improve stroke attribute handling --- third_party/assets/simple/ellipse.svg | 2 +- third_party/lib/main.dart | 2 +- third_party/lib/src/elements.dart | 1 + third_party/lib/src/parsers/xml_parsers.dart | 34 ++++++++++++++++++-- 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/third_party/assets/simple/ellipse.svg b/third_party/assets/simple/ellipse.svg index b7d25b2b7c37..2ea45661cf0d 100644 --- a/third_party/assets/simple/ellipse.svg +++ b/third_party/assets/simple/ellipse.svg @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 917c88af3685..a36442652ddf 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -51,7 +51,7 @@ class _MyHomePageState extends State { @override void initState() { super.initState(); - _dimension = 350.0; + _dimension = 100.0; assetNames.forEach((assetName) { _painters.add(new SvgImage.fromAsset( assetName, diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index 588eb47b0445..b08ae5431943 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -236,6 +236,7 @@ class SvgEllipse extends TransformableSvgElement { void _innerDraw(Canvas canvas) { if (stroke != null) canvas.drawOval(boundingRect, stroke); if (fill != null) canvas.drawOval(boundingRect, fill); + } } diff --git a/third_party/lib/src/parsers/xml_parsers.dart b/third_party/lib/src/parsers/xml_parsers.dart index f4a532152e37..91348aa8f0a1 100644 --- a/third_party/lib/src/parsers/xml_parsers.dart +++ b/third_party/lib/src/parsers/xml_parsers.dart @@ -19,10 +19,40 @@ Paint parseStroke(XmlElement el) { .toInt(); final stroke = parseColor(rawStroke).withAlpha(opacity); - // TODO: stroke types + final rawStrokeCap = el.getAttribute('stroke-linecap'); + StrokeCap strokeCap = rawStrokeCap == null + ? StrokeCap.butt + : StrokeCap.values.firstWhere( + (sc) => sc.toString() == 'StrokeCap.$rawStrokeCap', + orElse: () => StrokeCap.butt); + + final rawLineJoin = el.getAttribute('stroke-linejoin'); + StrokeJoin strokeJoin = rawLineJoin == null + ? StrokeJoin.miter + : StrokeJoin.values.firstWhere( + (sj) => sj.toString() == 'StrokeJoin.$rawLineJoin', + orElse: () => StrokeJoin.miter); + + final rawMiterLimit = el.getAttribute('stroke-miterlimit'); + final miterLimit = rawMiterLimit == null ? 4.0 : double.parse(rawMiterLimit); + + final rawStrokeWidth = el.getAttribute('stroke-width'); + final strokeWidth = + rawStrokeWidth == null ? 1.0 : double.parse(rawStrokeWidth); + + // TODO: Dash patterns not currently supported + if (el.getAttribute('stroke-dashoffset') != null || + el.getAttribute('stroke-dasharray') != null) { + print('Warning: Dash patterns not currently supported'); + } + return new Paint() ..color = stroke - ..style = PaintingStyle.stroke; + ..style = PaintingStyle.stroke + ..strokeWidth = strokeWidth + ..strokeCap = strokeCap + ..strokeJoin = strokeJoin + ..strokeMiterLimit = miterLimit; } Paint parseFill(XmlElement el, {bool isShape = true}) { From 85d40073c124e7ae4727bf7c30c41b290db5a200 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 13 Mar 2018 19:28:19 -0400 Subject: [PATCH 011/512] refactor to use paths/simplify code --- third_party/lib/src/elements.dart | 294 +++++++++------------------ third_party/lib/src/svg_painter.dart | 2 +- 2 files changed, 96 insertions(+), 200 deletions(-) diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index b08ae5431943..7f7c191c172f 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -5,107 +5,68 @@ import 'package:vector_math/vector_math_64.dart'; import 'parsers/parsers.dart'; import 'parsers/xml_parsers.dart'; -typedef SvgBaseElement SvgElementFactory(XmlElement el); - -abstract class SvgBaseElement { - static final Map _elements = { - 'circle': (el) => new SvgCircle.fromXml(el), - 'path': (el) => new SvgPath.fromXml(el), - 'g': (el) => new SvgGroup.fromXml(el), - 'rect': (el) => new SvgRect.fromXml(el), - 'polygon': (el) => new SvgPolygon.fromXml(el), - 'polyline': (el) => new SvgPolyline.fromXml(el), - 'ellipse': (el) => new SvgEllipse.fromXml(el), - 'line': (el) => new SvgLine.fromXml(el), - 'title': (el) => const SvgNoop(), - 'desc': (el) => const SvgNoop(), - }; - - final Paint stroke; - final Paint fill; - const SvgBaseElement(this.stroke, this.fill); - - void draw(Canvas canvas); +typedef Path SvgPathFactory(XmlElement el); +final Map _shapes = { + 'circle': (el) => pathFromSvgCircle(el), + 'path': (el) => pathFromSvgPath(el), + //'g': (el) => new SvgGroup.fromXml(el), + 'rect': (el) => pathFromSvgRect(el), + 'polygon': (el) => pathFromSvgPolygonOrLine(el), + 'polyline': (el) => pathFromSvgPolygonOrLine(el), + 'ellipse': (el) => pathFromSvgEllipse(el), + 'line': (el) => pathFromSvgLine(el), +}; + +class SvgElement { + final String name; + const SvgElement(this.name); + void draw(Canvas canvas) {} - factory SvgBaseElement.fromXml(XmlElement element) { - final ret = _elements[element.name.local]; - if (ret == null) { - throw new UnsupportedError('${element.name.local} not impleemnted yet'); + factory SvgElement.fromXml(XmlElement el) { + if (el.name.local == 'g') { + return new SvgGroup.fromXml(el); + } else if (_shapes.containsKey(el.name.local)) { + return new SvgShape.fromXml(el); + } else { + return new SvgElement(el.name.local); } - - return ret(element); } } -abstract class TransformableSvgElement extends SvgBaseElement { - final Matrix4 transform; - const TransformableSvgElement(this.transform, Paint stroke, Paint fill) - : super(stroke, fill); +class SvgShape extends SvgElement { + final Path path; + final Paint stroke; + final Paint fill; + + const SvgShape(this.path, this.stroke, this.fill, String elementName) + : assert(path != null, '$elementName had a null path'), + super(elementName); @override void draw(Canvas canvas) { - _startTransform(canvas); - _innerDraw(canvas); - _closeTransform(canvas); - } - - void _innerDraw(Canvas canvas); - - void _startTransform(Canvas canvas) { - if (transform != null) { - canvas.save(); - canvas.transform(transform.storage); - } - } - - void _closeTransform(Canvas canvas) { - if (transform != null) { - canvas.restore(); - } + if (stroke != null) canvas.drawPath(path, stroke); + if (fill != null) canvas.drawPath(path, fill); } -} - -class SvgNoop extends SvgBaseElement { - const SvgNoop() : super(null, null); - - void draw(Canvas canvas) {} -} - -class SvgCircle extends TransformableSvgElement { - final Offset center; - final double r; - - const SvgCircle( - this.center, this.r, Paint stroke, Paint fill, Matrix4 transform) - : super(transform, stroke, fill); - factory SvgCircle.fromXml(XmlElement el) { - final cx = double.parse(el.getAttribute('cx')); - final cy = double.parse(el.getAttribute('cy')); - final r = double.parse(el.getAttribute('r')); + factory SvgShape.fromXml(XmlElement el) { final stroke = parseStroke(el); final fill = parseFill(el); - final transform = parseTransform(el.getAttribute('transform')); - return new SvgCircle(new Offset(cx, cy), r, stroke, fill, transform); - } + final ret = _shapes[el.name.local]; - @override - void _innerDraw(Canvas canvas) { - if (stroke != null) canvas.drawCircle(center, r, stroke); - if (fill != null) canvas.drawCircle(center, r, fill); + return new SvgShape(ret(el), stroke, fill, el.name.local); } } -class SvgGroup extends TransformableSvgElement { - final List children; - const SvgGroup(this.children, Matrix4 transform) - : super(transform, null, null); +class SvgGroup extends SvgElement { + final List children; + final Matrix4 transform; + const SvgGroup(this.children, this.transform) : super('g'); factory SvgGroup.fromXml(XmlElement el) { - var children = new List(); + var children = new List(); el.children.forEach((child) { if (child is XmlElement) { - children.add(new SvgBaseElement.fromXml(child)); + children.add(new SvgElement.fromXml(child)); } }); @@ -121,146 +82,81 @@ class SvgGroup extends TransformableSvgElement { } @override - void _innerDraw(Canvas canvas) { + void draw(Canvas canvas) { + if (transform != null) { + canvas.save(); + canvas.transform(transform.storage); + } children.forEach((child) => child.draw(canvas)); + if (transform != null) { + canvas.restore(); + } } } -class SvgPath extends TransformableSvgElement { - final Path path; - final Matrix4 transform; - const SvgPath(this.path, Paint stroke, Paint fill, {this.transform}) - : super(transform, stroke, fill); +Path transformPath(Path path, XmlElement el) { + assert(path != null); + assert(el != null); - factory SvgPath.fromXml(XmlElement el) { - final d = el.getAttribute('d'); - final p = Path.parseSvgPathData(d); + final transform = parseTransform(el.getAttribute('transform')); - final transform = parseTransform(el.getAttribute('transform')); - return new SvgPath(p, parseStroke(el), parseFill(el), transform: transform); - } - - @override - void _innerDraw(Canvas canvas) { - if (stroke != null) canvas.drawPath(path, stroke); - if (fill != null) canvas.drawPath(path, fill); + if (transform != null) { + return path.transform(transform.storage); + } else { + return path; } } -class SvgRect extends TransformableSvgElement { - final Rect rect; - const SvgRect(this.rect, Paint stroke, Paint fill, Matrix4 transform) - : super(transform, stroke, fill); +Path pathFromSvgCircle(XmlElement el) { + final cx = double.parse(el.getAttribute('cx')); + final cy = double.parse(el.getAttribute('cy')); + final r = double.parse(el.getAttribute('r')); - factory SvgRect.fromXml(XmlElement el) { - final x = double.parse(el.getAttribute('x')); - final y = double.parse(el.getAttribute('y')); - final w = double.parse(el.getAttribute('width')); - final h = double.parse(el.getAttribute('height')); - - final transform = parseTransform(el.getAttribute('transform')); - return new SvgRect(new Rect.fromLTWH(x, y, w, h), parseStroke(el), - parseFill(el), transform); - } - - @override - void _innerDraw(Canvas canvas) { - if (stroke != null) canvas.drawRect(rect, stroke); - if (fill != null) canvas.drawRect(rect, fill); - } + final path = new Path() + ..addOval(new Rect.fromLTRB(cx - r, cy - r, cx + r, cy + r)); + return transformPath(path, el); } -class SvgPolygon extends TransformableSvgElement { - final Path path; - - const SvgPolygon(this.path, Paint stroke, Paint fill, Matrix4 transform) - : super(transform, stroke, fill); - - factory SvgPolygon.fromXml(XmlElement el) { - // flutter draws polygons without filling them. Convert to path. - final path = Path.parseSvgPathData('M' + el.getAttribute('points') + 'z'); - - final transform = parseTransform(el.getAttribute('transform')); - return new SvgPolygon(path, parseStroke(el), parseFill(el), transform); - } - - @override - void _innerDraw(Canvas canvas) { - //canvas.drawRawPoints(PointMode.polygon, points, paint); - if (stroke != null) canvas.drawPath(path, stroke); - if (fill != null) canvas.drawPath(path, fill); - } +Path pathFromSvgPath(XmlElement el) { + final d = el.getAttribute('d'); + return transformPath(Path.parseSvgPathData(d), el); } -class SvgPolyline extends TransformableSvgElement { - final Path path; - - const SvgPolyline(this.path, Paint stroke, Paint fill, Matrix4 transform) - : super(transform, stroke, fill); - - factory SvgPolyline.fromXml(XmlElement el) { - // flutter draws polygons without filling them. Convert to path. - final path = Path.parseSvgPathData('M' + el.getAttribute('points')); - - final transform = parseTransform(el.getAttribute('transform')); - return new SvgPolyline(path, parseStroke(el), parseFill(el), transform); - } +Path pathFromSvgRect(XmlElement el) { + final x = double.parse(el.getAttribute('x')); + final y = double.parse(el.getAttribute('y')); + final w = double.parse(el.getAttribute('width')); + final h = double.parse(el.getAttribute('height')); - @override - void _innerDraw(Canvas canvas) { - if (stroke != null) canvas.drawPath(path, stroke); - if (fill != null) canvas.drawPath(path, fill); - } + final path = new Path()..addRect(new Rect.fromLTWH(x, y, w, h)); + return transformPath(path, el); } -class SvgEllipse extends TransformableSvgElement { - final Rect boundingRect; - - const SvgEllipse( - this.boundingRect, Paint stroke, Paint fill, Matrix4 transform) - : super(transform, stroke, fill); - - factory SvgEllipse.fromXml(XmlElement el) { - final cx = double.parse(el.getAttribute('cx')); - final cy = double.parse(el.getAttribute('cy')); - final rx = double.parse(el.getAttribute('rx')); - final ry = double.parse(el.getAttribute('ry')); +Path pathFromSvgPolygonOrLine(XmlElement el) { + final path = Path.parseSvgPathData('M' + el.getAttribute('points') + 'z'); - Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); - - final transform = parseTransform(el.getAttribute('transform')); - return new SvgEllipse(r, parseStroke(el), parseFill(el), transform); - } - - @override - void _innerDraw(Canvas canvas) { - if (stroke != null) canvas.drawOval(boundingRect, stroke); - if (fill != null) canvas.drawOval(boundingRect, fill); - - } + return transformPath(path, el); } -class SvgLine extends TransformableSvgElement { - final Offset start; - final Offset end; +Path pathFromSvgEllipse(XmlElement el) { + final cx = double.parse(el.getAttribute('cx')); + final cy = double.parse(el.getAttribute('cy')); + final rx = double.parse(el.getAttribute('rx')); + final ry = double.parse(el.getAttribute('ry')); - const SvgLine(this.start, this.end, Paint stroke, Matrix4 transform) - : super(transform, stroke, null); + Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); - factory SvgLine.fromXml(XmlElement el) { - final x1 = double.parse(el.getAttribute('x1')); - final x2 = double.parse(el.getAttribute('x2')); - final y1 = double.parse(el.getAttribute('y1')); - final y2 = double.parse(el.getAttribute('y2')); - final paint = parseStroke(el); + return transformPath(new Path()..addOval(r), el); +} - final transform = parseTransform(el.getAttribute('transform')); - return new SvgLine( - new Offset(x1, x2), new Offset(y1, y2), paint, transform); - } +Path pathFromSvgLine(XmlElement el) { + final x1 = double.parse(el.getAttribute('x1')); + final x2 = double.parse(el.getAttribute('x2')); + final y1 = double.parse(el.getAttribute('y1')); + final y2 = double.parse(el.getAttribute('y2')); - @override - void _innerDraw(Canvas canvas) { - canvas.drawLine(start, end, stroke); - } + final path = new Path() + ..moveTo(x1, x2) + ..lineTo(y1, y2); + return transformPath(path, el); } diff --git a/third_party/lib/src/svg_painter.dart b/third_party/lib/src/svg_painter.dart index 1c171aa3f25b..1e33c380f45f 100644 --- a/third_party/lib/src/svg_painter.dart +++ b/third_party/lib/src/svg_painter.dart @@ -19,7 +19,7 @@ class SvgPainter extends CustomPainter { size.width / vbRect.size.width, size.height / vbRect.size.height); for (var el in _rawSvg.rootElement.children) { if (el is! XmlElement) continue; - final svgEl = new SvgBaseElement.fromXml(el); + final svgEl = new SvgElement.fromXml(el); svgEl.draw(canvas); } } From ce07f0d4873e4c4e3b8470fcb335c8c0c809bbff Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 25 Apr 2018 23:37:22 -0400 Subject: [PATCH 012/512] path parsing --- third_party/lib/main.dart | 4 - third_party/lib/src/elements.dart | 8 +- third_party/lib/src/parsers/colors.dart | 3 +- third_party/lib/src/parsers/parsers.dart | 1 - third_party/lib/src/parsers/path.dart | 891 +++++++++++++++++++ third_party/lib/src/parsers/xml_parsers.dart | 8 +- third_party/lib/svg.dart | 1 - third_party/pubspec.lock | 27 +- third_party/test/path_parse_test.dart | 68 ++ third_party/test/widget_test.dart | 29 - 10 files changed, 978 insertions(+), 62 deletions(-) create mode 100644 third_party/lib/src/parsers/path.dart create mode 100644 third_party/test/path_parse_test.dart delete mode 100644 third_party/test/widget_test.dart diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index a36442652ddf..0df4f7b5893f 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -1,8 +1,4 @@ -import 'dart:async'; - import 'package:flutter/material.dart'; -import 'package:xml/xml.dart'; - import 'package:flutter_svg/svg.dart'; const List assetNames = const [ diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index 7f7c191c172f..cfee0a5d96ea 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:xml/xml.dart'; import 'package:vector_math/vector_math_64.dart'; import 'parsers/parsers.dart'; +import 'parsers/path.dart'; import 'parsers/xml_parsers.dart'; typedef Path SvgPathFactory(XmlElement el); @@ -113,13 +114,14 @@ Path pathFromSvgCircle(XmlElement el) { final r = double.parse(el.getAttribute('r')); final path = new Path() - ..addOval(new Rect.fromLTRB(cx - r, cy - r, cx + r, cy + r)); + ..addOval(new Rect.fromCircle(center: new Offset(cx, cy), radius: r)); return transformPath(path, el); } Path pathFromSvgPath(XmlElement el) { final d = el.getAttribute('d'); - return transformPath(Path.parseSvgPathData(d), el); + final Path p = parseSvgPathData(d); + return transformPath(p, el); } Path pathFromSvgRect(XmlElement el) { @@ -133,7 +135,7 @@ Path pathFromSvgRect(XmlElement el) { } Path pathFromSvgPolygonOrLine(XmlElement el) { - final path = Path.parseSvgPathData('M' + el.getAttribute('points') + 'z'); + final path = parseSvgPathData('M' + el.getAttribute('points') + 'z'); return transformPath(path, el); } diff --git a/third_party/lib/src/parsers/colors.dart b/third_party/lib/src/parsers/colors.dart index 129d5d0cb41d..6f7f4c196d25 100644 --- a/third_party/lib/src/parsers/colors.dart +++ b/third_party/lib/src/parsers/colors.dart @@ -13,8 +13,7 @@ Color parseColor(String colorString) { final b = colorString[3]; colorString = '#$r$r$g$g$b$b'; } - int color = int.parse(colorString.substring(1), - radix: 16, onError: (source) => null); + int color = int.parse(colorString.substring(1), radix: 16); if (colorString.length == 7) { return new Color(color |= 0x00000000ff000000); diff --git a/third_party/lib/src/parsers/parsers.dart b/third_party/lib/src/parsers/parsers.dart index 13c73968be16..eba7e28cfea9 100644 --- a/third_party/lib/src/parsers/parsers.dart +++ b/third_party/lib/src/parsers/parsers.dart @@ -1,5 +1,4 @@ import 'dart:ui'; -import 'dart:typed_data'; import 'dart:math'; import 'package:vector_math/vector_math_64.dart'; diff --git a/third_party/lib/src/parsers/path.dart b/third_party/lib/src/parsers/path.dart new file mode 100644 index 000000000000..e22bd957050e --- /dev/null +++ b/third_party/lib/src/parsers/path.dart @@ -0,0 +1,891 @@ +// This code has been "translated" largely from the Chromium/blink source +// for SVG path parsing. + +import 'dart:async'; +import 'dart:ui' show Path, Offset; +import 'dart:math' show sqrt, max, pi, tan, sin, cos, pow; +import 'package:vector_math/vector_math.dart' show Matrix4; + +const double _twoPiFloat = pi * 2.0; +const double _piOverTwoFloat = pi / 2.0; + +Path parseSvgPathData(String svg) { + final SvgPathStringSource parser = new SvgPathStringSource(svg); + final Path path = new Path(); + final SvgPathNormalizer normalizer = new SvgPathNormalizer(); + for (PathSegmentData seg in parser.parseSegments()) { + normalizer.emitSegment(seg, path); + } + return path; +} + +/// SvgPathSegType enumerates the various path segment commands. +/// +/// [AsciiConstants] houses the ASCII numeric values of these commands +enum SvgPathSegType { + /// Indicates initial state or error + unknown, + + /// Z or z + close, + + /// M + moveToAbs, + + /// m + moveToRel, + + /// L + lineToAbs, + + /// l + lineToRel, + + /// C + cubicToAbs, + + /// c + cubicToRel, + + /// Q + quadToAbs, + + /// q + quadToRel, + + /// A + arcToAbs, + + /// a + arcToRel, + + /// H + lineToHorizontalAbs, + + /// h + lineToHorizontalRel, + + /// V + lineToVerticalAbs, + + /// v + lineToVerticalRel, + + /// S + smoothCubicToAbs, + + /// s + smoothCubicToRel, + + /// T + smoothQuadToAbs, + + /// t + smoothQuadToRel +} + +/// Character constants used internally. Note that this parser does not +/// properly support non-ascii characters in the path, but it does support +/// unicode encoding. +/// +/// Only contains values that are used by the parser (does not contain the full +/// ASCII set). +class AsciiConstants { + const AsciiConstants._(); + + static SvgPathSegType mapLetterToSegmentType(int lookahead) { + return AsciiConstants.letterToSegmentType[lookahead] ?? + SvgPathSegType.unknown; + } + + /// Map to go from ASCII constant to [SvgPathSegType] + static const Map letterToSegmentType = const { + upperZ: SvgPathSegType.close, + lowerZ: SvgPathSegType.close, + upperM: SvgPathSegType.moveToAbs, + lowerM: SvgPathSegType.moveToRel, + upperL: SvgPathSegType.lineToAbs, + lowerL: SvgPathSegType.lineToRel, + upperC: SvgPathSegType.cubicToAbs, + lowerC: SvgPathSegType.cubicToRel, + upperQ: SvgPathSegType.quadToAbs, + lowerQ: SvgPathSegType.quadToRel, + upperA: SvgPathSegType.arcToAbs, + lowerA: SvgPathSegType.arcToRel, + upperH: SvgPathSegType.lineToHorizontalAbs, + lowerH: SvgPathSegType.lineToHorizontalRel, + upperV: SvgPathSegType.lineToVerticalAbs, + lowerV: SvgPathSegType.lineToVerticalRel, + upperS: SvgPathSegType.smoothCubicToAbs, + lowerS: SvgPathSegType.smoothCubicToRel, + upperT: SvgPathSegType.smoothQuadToAbs, + lowerT: SvgPathSegType.smoothQuadToRel, + }; + + /// `\t` (horizontal tab). + static const int slashT = 9; + + /// `\n` (newline). + static const int slashN = 10; + + /// `\f` (form feed). + static const int slashF = 12; + + /// `\r` (carriage return). + static const int slashR = 13; + + /// ` ` (space). + static const int space = 32; + + /// `+` (plus). + static const int plus = 43; + + /// `,` (comma). + static const int comma = 44; + + /// `-` (minus). + static const int minus = 45; + + /// `.` (period). + static const int period = 46; + + /// 0 (the number zero). + static const int number0 = 48; + + /// 1 (the number one). + static const int number1 = 49; + + /// 2 (the number two). + static const int number2 = 50; + + /// 3 (the number three). + static const int number3 = 51; + + /// 4 (the number four). + static const int number4 = 52; + + /// 5 (the number five). + static const int number5 = 53; + + /// 6 (the number six). + static const int number6 = 54; + + /// 7 (the number seven). + static const int number7 = 55; + + /// 8 (the number eight). + static const int number8 = 56; + + /// 9 (the number nine). + static const int number9 = 57; + + /// A + static const int upperA = 65; + + /// C + static const int upperC = 67; + + /// E + static const int upperE = 69; + + /// H + static const int upperH = 72; + + /// L + static const int upperL = 76; + + /// M + static const int upperM = 77; + + /// Q + static const int upperQ = 81; + + /// S + static const int upperS = 83; + + /// T + static const int upperT = 84; + + /// V + static const int upperV = 86; + + /// Z + static const int upperZ = 90; + + /// a + static const int lowerA = 97; + + /// c + static const int lowerC = 99; + + /// e + static const int lowerE = 101; + + /// h + static const int lowerH = 104; + + /// l + static const int lowerL = 108; + + /// m + static const int lowerM = 109; + + /// q + static const int lowerQ = 113; + + /// s + static const int lowerS = 115; + + /// t + static const int lowerT = 116; + + /// v + static const int lowerV = 118; + + /// x + static const int lowerX = 120; + + /// z + static const int lowerZ = 122; + + /// `~` (tilde) + static const int tilde = 126; +} + +class SvgPathStringSource { + SvgPathSegType _previousCommand; + List _codePoints; + int _idx; + + SvgPathStringSource(String string) { + assert(string != null); + _previousCommand = SvgPathSegType.unknown; + _codePoints = string.codeUnits; + _idx = 0; + _skipOptionalSvgSpaces(); + } + + bool _isHtmlSpace(int character) { + // Histogram from Apple's page load test combined with some ad hoc browsing + // some other test suites. + // + // 82%: 216330 non-space characters, all > U+0020 + // 11%: 30017 plain space characters, U+0020 + // 5%: 12099 newline characters, U+000A + // 2%: 5346 tab characters, U+0009 + // + // No other characters seen. No U+000C or U+000D, and no other control + // characters. Accordingly, we check for non-spaces first, then space, then + // newline, then tab, then the other characters. + + return character <= AsciiConstants.space && + (character == AsciiConstants.space || + character == AsciiConstants.slashN || + character == AsciiConstants.slashT || + character == AsciiConstants.slashR || + character == AsciiConstants.slashF); + } + + bool _skipOptionalSvgSpaces() { + while (_idx < _codePoints.length && _isHtmlSpace(_codePoints[_idx])) _idx++; + return _idx < _codePoints.length; + } + + bool _skipOptionalSvgSpacesOrDelimiter( + [int delimiter = AsciiConstants.comma]) { + if (_idx < _codePoints.length && + !_isHtmlSpace(_codePoints[_idx]) && + _codePoints[_idx] != delimiter) return false; + if (_skipOptionalSvgSpaces()) { + if (_idx < _codePoints.length && _codePoints[_idx] == delimiter) { + _idx++; + _skipOptionalSvgSpaces(); + } + } + return _idx < _codePoints.length; + } + + bool _isNumberStart(int lookahead) { + return (lookahead >= AsciiConstants.number0 && + lookahead <= AsciiConstants.number9) || + lookahead == AsciiConstants.plus || + lookahead == AsciiConstants.minus || + lookahead == AsciiConstants.period; + } + + SvgPathSegType _maybeImplicitCommand( + int lookahead, SvgPathSegType nextCommand) { + // Check if the current lookahead may start a number - in which case it + // could be the start of an implicit command. The 'close' command does not + // have any parameters though and hence can't have an implicit + // 'continuation'. + if (!_isNumberStart(lookahead) || _previousCommand == SvgPathSegType.close) + return nextCommand; + // Implicit continuations of moveto command translate to linetos. + if (_previousCommand == SvgPathSegType.moveToAbs) { + return SvgPathSegType.lineToAbs; + } + if (_previousCommand == SvgPathSegType.moveToRel) { + return SvgPathSegType.lineToRel; + } + return _previousCommand; + } + + bool _isValidRange(double x) { + return x >= -double.maxFinite && x <= double.maxFinite; + } + + bool _isValidExponent(double x) { + return x >= 37 && x <= 38; + } + + // We use this generic parseNumber function to allow the Path parsing code to + // work at a higher precision internally, without any unnecessary runtime cost + // or code complexity. + double _parseNumber() { + _skipOptionalSvgSpaces(); + + // read the sign + int sign = 1; + int end = _codePoints.length; + if (_idx < end && _codePoints[_idx] == AsciiConstants.plus) + _idx++; + else if (_idx < end && _codePoints[_idx] == AsciiConstants.minus) { + _idx++; + sign = -1; + } + + if (_idx == end || + ((_codePoints[_idx] < AsciiConstants.number0 || + _codePoints[_idx] > AsciiConstants.number9) && + _codePoints[_idx] != AsciiConstants.period)) + // The first character of a number must be one of [0-9+-.] + throw new StateError( + 'First character of a number must be one of [0-9+-.]'); + + // read the integer part, build right-to-left + final int digitsStart = _idx; + while (_idx < end && + _codePoints[_idx] >= AsciiConstants.number0 && + _codePoints[_idx] <= AsciiConstants.number9) + ++_idx; // Advance to first non-digit. + + double integer = 0.0; + if (_idx != digitsStart) { + int ptrScanIntPart = _idx - 1; + int multiplier = 1; + while (ptrScanIntPart >= digitsStart) { + integer += multiplier * + (_codePoints[ptrScanIntPart--] - AsciiConstants.number0); + + multiplier *= 10; + } + // Bail out early if this overflows. + if (!_isValidRange(integer)) throw new StateError('Numeric overflow'); + } + + double decimal = 0.0; + if (_idx < end && _codePoints[_idx] == AsciiConstants.period) { + // read the decimals + _idx++; + + // There must be a least one digit following the . + if (_idx >= end || + _codePoints[_idx] < AsciiConstants.number0 || + _codePoints[_idx] > AsciiConstants.number9) + throw new StateError( + 'There must be at least one digit following the .'); + + double frac = 1.0; + while (_idx < end && + _codePoints[_idx] >= AsciiConstants.number0 && + _codePoints[_idx] <= AsciiConstants.number9) { + frac *= 0.1; + decimal += (_codePoints[_idx++] - AsciiConstants.number0) * frac; + } + } + + // When we get here we should have consumed either a digit for the integer + // part or a fractional part (with at least one digit after the '.'.) + assert(digitsStart != _idx); + + double number = integer + decimal; + number *= sign; + + // read the exponent part + if (_idx + 1 < end && + (_codePoints[_idx] == AsciiConstants.lowerE || + _codePoints[_idx] == AsciiConstants.upperE) && + (_codePoints[_idx + 1] != AsciiConstants.lowerX && + _codePoints[_idx + 1] != AsciiConstants.lowerM)) { + _idx++; + + // read the sign of the exponent + bool exponentIsNegative = false; + if (_codePoints[_idx] == AsciiConstants.plus) + _idx++; + else if (_codePoints[_idx] == AsciiConstants.minus) { + _idx++; + exponentIsNegative = true; + } + + // There must be an exponent + if (_idx >= end || + _codePoints[_idx] < AsciiConstants.number0 || + _codePoints[_idx] > AsciiConstants.number9) + throw new StateError('Missing exponent'); + + double exponent = 0.0; + while (_idx < end && + _codePoints[_idx] >= AsciiConstants.number0 && + _codePoints[_idx] <= AsciiConstants.number9) { + exponent *= 10.0; + exponent += _codePoints[_idx] - AsciiConstants.number0; + _idx++; + } + if (exponentIsNegative) exponent = -exponent; + // Make sure exponent is valid. + if (!_isValidExponent(exponent)) throw new StateError('Invalid exponent'); + if (exponent != 0) number *= pow(10.0, exponent); + } + + // Don't return Infinity() or NaN(). + if (!_isValidRange(number)) throw new StateError('Numeric overflow'); + + // if (mode & kAllowTrailingWhitespace) + _skipOptionalSvgSpacesOrDelimiter(); + + return number; + } + + bool _parseArcFlag() { + if (!hasMoreData) throw new StateError('Expected more data'); + final int flagChar = _codePoints[_idx]; + _idx++; + _skipOptionalSvgSpacesOrDelimiter(); + + if (flagChar == AsciiConstants.number0) + return false; + else if (flagChar == AsciiConstants.number1) + return true; + else + throw new StateError('Invalid flag value'); + } + + bool get hasMoreData => _idx < _codePoints.length; + + Iterable parseSegments() sync* { + while (hasMoreData) { + yield parseSegment(); + } + } + + PathSegmentData parseSegment() { + assert(hasMoreData); + PathSegmentData segment = new PathSegmentData(); + int lookahead = _codePoints[_idx]; + SvgPathSegType command = AsciiConstants.mapLetterToSegmentType(lookahead); + if (_previousCommand == SvgPathSegType.unknown) { + // First command has to be a moveto. + if (command != SvgPathSegType.moveToRel && + command != SvgPathSegType.moveToAbs) { + throw new StateError('Expected to find moveTo command'); + // SetErrorMark(SVGParseStatus::kExpectedMoveToCommand); + // return segment; + } + // Consume command letter. + _idx++; + } else if (command == SvgPathSegType.unknown) { + // Possibly an implicit command. + assert(_previousCommand != SvgPathSegType.unknown); + command = _maybeImplicitCommand(lookahead, command); + if (command == null || command == SvgPathSegType.unknown) { + throw new StateError('Expected a path command'); + } + } else { + // Valid explicit command. + _idx++; + } + + segment.command = _previousCommand = command; + + switch (segment.command) { + case SvgPathSegType.cubicToRel: + case SvgPathSegType.cubicToAbs: + segment.point1 = new Offset(_parseNumber(), _parseNumber()); + continue cubic_smooth; + case SvgPathSegType.smoothCubicToRel: + cubic_smooth: + case SvgPathSegType.smoothCubicToAbs: + segment.point2 = new Offset(_parseNumber(), _parseNumber()); + continue quad_smooth; + case SvgPathSegType.moveToRel: + case SvgPathSegType.moveToAbs: + case SvgPathSegType.lineToRel: + case SvgPathSegType.lineToAbs: + case SvgPathSegType.smoothQuadToRel: + quad_smooth: + case SvgPathSegType.smoothQuadToAbs: + segment.targetPoint = new Offset(_parseNumber(), _parseNumber()); + break; + case SvgPathSegType.lineToHorizontalRel: + case SvgPathSegType.lineToHorizontalAbs: + segment.targetPoint = + new Offset(_parseNumber(), segment.targetPoint?.dy ?? 0.0); + break; + case SvgPathSegType.lineToVerticalRel: + case SvgPathSegType.lineToVerticalAbs: + segment.targetPoint = + new Offset(segment.targetPoint?.dx ?? 0.0, _parseNumber()); + break; + case SvgPathSegType.close: + _skipOptionalSvgSpaces(); + break; + case SvgPathSegType.quadToRel: + case SvgPathSegType.quadToAbs: + segment.point1 = new Offset(_parseNumber(), _parseNumber()); + segment.targetPoint = new Offset(_parseNumber(), _parseNumber()); + + break; + case SvgPathSegType.arcToRel: + case SvgPathSegType.arcToAbs: + segment.point1 = new Offset(_parseNumber(), _parseNumber()); + segment.arcAngle = _parseNumber(); + segment.arcLarge = _parseArcFlag(); + segment.arcSweep = _parseArcFlag(); + segment.targetPoint = new Offset(_parseNumber(), _parseNumber()); + break; + case SvgPathSegType.unknown: + throw new StateError('Unknown segment command'); + } + + return segment; + } +} + +class OffsetHelper { + static Offset reflectedPoint(Offset reflectedIn, Offset pointToReflect) { + return new Offset(2 * reflectedIn.dx - pointToReflect.dx, + 2 * reflectedIn.dy - pointToReflect.dy); + } + + static const double _kOneOverThree = 1.0 / 3.0; + + /// Blend the points with a ratio (1/3):(2/3). + static Offset blendPoints(Offset p1, Offset p2) { + return Offset((p1.dx + 2 * p2.dx) * _kOneOverThree, + (p1.dy + 2 * p2.dy) * _kOneOverThree); + } +} + +bool isCubicCommand(SvgPathSegType command) { + return command == SvgPathSegType.cubicToAbs || + command == SvgPathSegType.cubicToRel || + command == SvgPathSegType.smoothCubicToAbs || + command == SvgPathSegType.smoothCubicToRel; +} + +bool isQuadraticCommand(SvgPathSegType command) { + return command == SvgPathSegType.quadToAbs || + command == SvgPathSegType.quadToRel || + command == SvgPathSegType.smoothQuadToAbs || + command == SvgPathSegType.smoothQuadToRel; +} + +class PathSegmentData { + PathSegmentData() + : command = SvgPathSegType.unknown, + arcSweep = false, + arcLarge = false; + + Offset get arcRadii => point1; + + double get arcAngle => point2.dx; + set arcAngle(double angle) => point2 = new Offset(angle, point2.dy); + + double get r1 => arcRadii.dx; + double get r2 => arcRadii.dy; + + bool get largeArcFlag => arcLarge; + bool get sweepFlag => arcSweep; + + double get x => targetPoint.dx; + double get y => targetPoint.dy; + + double get x1 => point1.dx; + double get y1 => point1.dy; + + double get x2 => point2.dx; + double get y2 => point2.dy; + + SvgPathSegType command; + Offset targetPoint; + Offset point1; + Offset point2; + bool arcSweep; + bool arcLarge; + + @override + String toString() { + return 'PathSegmentData{$command $targetPoint $point1 $point2 $arcSweep $arcLarge}'; + } +} + +class SvgPathNormalizer { + Offset _currentPoint = Offset.zero; + Offset _subPathPoint = Offset.zero; + Offset _controlPoint = Offset.zero; + SvgPathSegType _lastCommand = SvgPathSegType.unknown; + + void emitSegment(PathSegmentData segment, Path path) { + PathSegmentData normSeg = segment; + assert( + normSeg.command == SvgPathSegType.close || normSeg.targetPoint != null); + assert(_currentPoint != null); + // Convert relative points to absolute points. + switch (segment.command) { + case SvgPathSegType.quadToRel: + normSeg.point1 += _currentPoint; + normSeg.targetPoint += _currentPoint; + break; + case SvgPathSegType.cubicToRel: + normSeg.point1 += _currentPoint; + continue smooth_rel; + smooth_rel: + case SvgPathSegType.smoothCubicToRel: + normSeg.point2 += _currentPoint; + continue arc_rel; + case SvgPathSegType.moveToRel: + case SvgPathSegType.lineToRel: + case SvgPathSegType.lineToHorizontalRel: + case SvgPathSegType.lineToVerticalRel: + case SvgPathSegType.smoothQuadToRel: + arc_rel: + case SvgPathSegType.arcToRel: + normSeg.targetPoint += _currentPoint; + break; + case SvgPathSegType.lineToHorizontalAbs: + normSeg.targetPoint = + new Offset(normSeg.targetPoint.dx, _currentPoint.dy); + break; + case SvgPathSegType.lineToVerticalAbs: + normSeg.targetPoint = + new Offset(_currentPoint.dx, normSeg.targetPoint.dy); + break; + case SvgPathSegType.close: + // Reset m_currentPoint for the next path. + normSeg.targetPoint = _subPathPoint; + break; + default: + break; + } + + // Update command verb, handle smooth segments and convert quadratic curve + // segments to cubics. + switch (segment.command) { + case SvgPathSegType.moveToRel: + case SvgPathSegType.moveToAbs: + _subPathPoint = normSeg.targetPoint; + normSeg.command = SvgPathSegType.moveToAbs; + path.moveTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy); + break; + case SvgPathSegType.lineToRel: + case SvgPathSegType.lineToAbs: + case SvgPathSegType.lineToHorizontalRel: + case SvgPathSegType.lineToHorizontalAbs: + case SvgPathSegType.lineToVerticalRel: + case SvgPathSegType.lineToVerticalAbs: + normSeg.command = SvgPathSegType.lineToAbs; + path.lineTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy); + break; + case SvgPathSegType.close: + normSeg.command = SvgPathSegType.close; + path.close(); + break; + case SvgPathSegType.smoothCubicToRel: + case SvgPathSegType.smoothCubicToAbs: + if (!isCubicCommand(_lastCommand)) + normSeg.point1 = _currentPoint; + else + normSeg.point1 = + OffsetHelper.reflectedPoint(_currentPoint, _controlPoint); + continue cubic_abs2; + case SvgPathSegType.cubicToRel: + cubic_abs2: + case SvgPathSegType.cubicToAbs: + _controlPoint = normSeg.point2; + normSeg.command = SvgPathSegType.cubicToAbs; + path.cubicTo(normSeg.point1.dx, normSeg.point1.dy, normSeg.point2.dx, + normSeg.point2.dy, normSeg.targetPoint.dx, normSeg.targetPoint.dy); + break; + case SvgPathSegType.smoothQuadToRel: + case SvgPathSegType.smoothQuadToAbs: + if (!isQuadraticCommand(_lastCommand)) + normSeg.point1 = _currentPoint; + else + normSeg.point1 = + OffsetHelper.reflectedPoint(_currentPoint, _controlPoint); + continue quad_abs2; + case SvgPathSegType.quadToRel: + quad_abs2: + case SvgPathSegType.quadToAbs: + // Save the unmodified control point. + _controlPoint = normSeg.point1; + normSeg.point1 = OffsetHelper.blendPoints(_currentPoint, _controlPoint); + normSeg.point2 = + OffsetHelper.blendPoints(normSeg.targetPoint, _controlPoint); + normSeg.command = SvgPathSegType.cubicToAbs; + path.cubicTo(normSeg.point1.dx, normSeg.point1.dy, normSeg.point2.dx, + normSeg.point2.dy, normSeg.targetPoint.dx, normSeg.targetPoint.dy); + break; + case SvgPathSegType.arcToRel: + case SvgPathSegType.arcToAbs: + if (!_decomposeArcToCubic(_currentPoint, normSeg, path)) { + // On failure, emit a line segment to the target point. + normSeg.command = SvgPathSegType.lineToAbs; + path.lineTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy); + } else { + // decomposeArcToCubic() has already emitted the normalized + // segments, so set command to PathSegArcAbs, to skip any further + // emit. + normSeg.command = SvgPathSegType.arcToAbs; + } + break; + default: + throw new StateError('Invalid command type in path'); + } + + // if (normSeg.command != SvgPathSegType.arcToAbs) { + // + // //consumer_.EmitSegment(normSeg); + // } + + _currentPoint = normSeg.targetPoint; + + if (!isCubicCommand(segment.command) && + !isQuadraticCommand(segment.command)) { + _controlPoint = _currentPoint; + } + + _lastCommand = segment.command; + } + +// This works by converting the SVG arc to "simple" beziers. +// Partly adapted from Niko's code in kdelibs/kdecore/svgicons. +// See also SVG implementation notes: +// http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter + bool _decomposeArcToCubic( + Offset currentPoint, PathSegmentData arcSegment, Path path) { + // If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a + // "lineto") joining the endpoints. + // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters + double rx = arcSegment.arcRadii.dx.abs(); + double ry = arcSegment.arcRadii.dy.abs(); + if (rx == 0 || ry == 0) { + return false; + } + + // If the current point and target point for the arc are identical, it should + // be treated as a zero length path. This ensures continuity in animations. + if (arcSegment.targetPoint == currentPoint) { + return false; + } + + double angle = arcSegment.arcAngle; + + Offset midPointDistance = currentPoint - arcSegment.targetPoint; + midPointDistance.scale(0.5, 0.5); + + Matrix4 pointTransform = new Matrix4.identity(); + pointTransform.rotateZ(-angle); + + Offset transformedMidPoint = _mapPoint( + pointTransform, Offset(midPointDistance.dx, midPointDistance.dy)); + double squareRx = rx * rx; + double squareRy = ry * ry; + double squareX = transformedMidPoint.dx * transformedMidPoint.dx; + double squareY = transformedMidPoint.dy * transformedMidPoint.dy; + + // Check if the radii are big enough to draw the arc, scale radii if not. + // http://www.w3.org/TR/SVG/implnote.html#ArcCorrectionOutOfRangeRadii + double radiiScale = squareX / squareRx + squareY / squareRy; + if (radiiScale > 1) { + rx *= sqrt(radiiScale); + ry *= sqrt(radiiScale); + } + + pointTransform.setIdentity(); + pointTransform.scale(1 / rx, 1 / ry); + pointTransform.rotateZ(-angle); + + Offset point1 = _mapPoint(pointTransform, currentPoint); + Offset point2 = _mapPoint(pointTransform, arcSegment.targetPoint); + Offset delta = point2 - point1; + + double d = delta.dx * delta.dx + delta.dy * delta.dy; + double scaleFactorSquared = max(1 / d - 0.25, 0.0); + + double scaleFactor = sqrt(scaleFactorSquared); + if (arcSegment.arcSweep == arcSegment.arcLarge) scaleFactor = -scaleFactor; + + delta.scale(scaleFactor, scaleFactor); + Offset centerPoint = point1 + point2; + centerPoint.scale(0.5, 0.5); + centerPoint.translate(-delta.dx, delta.dy); + + double theta1 = (point1 - centerPoint).direction; + double theta2 = (point2 - centerPoint).direction; + + double thetaArc = theta2 - theta1; + if (thetaArc < 0 && arcSegment.arcSweep) + thetaArc += _twoPiFloat; + else if (thetaArc > 0 && !arcSegment.arcSweep) thetaArc -= _twoPiFloat; + + pointTransform.setIdentity(); + pointTransform.rotateZ(angle); + pointTransform.scale(rx, ry); + + // Some results of atan2 on some platform implementations are not exact + // enough. So that we get more cubic curves than expected here. Adding 0.001f + // reduces the count of sgements to the correct count. + final int segments = (thetaArc / (_piOverTwoFloat + 0.001)).abs().ceil(); + for (int i = 0; i < segments; ++i) { + final double startTheta = theta1 + i * thetaArc / segments; + final double endTheta = theta1 + (i + 1) * thetaArc / segments; + + final double t = (8 / 6.0) * tan(0.25 * (endTheta - startTheta)); + if (!t.isFinite) return false; + final double sinStartTheta = sin(startTheta); + final double cosStartTheta = cos(startTheta); + final double sinEndTheta = sin(endTheta); + final double cosEndTheta = cos(endTheta); + + point1 = Offset( + cosStartTheta - t * sinStartTheta, sinStartTheta + t * cosStartTheta); + point1.translate(centerPoint.dx, centerPoint.dy); + final Offset targetPoint = new Offset(cosEndTheta, sinEndTheta); + targetPoint.translate(centerPoint.dx, centerPoint.dy); + point2 = targetPoint; + point2.translate(t * sinEndTheta, -t * cosEndTheta); + + final PathSegmentData cubicSegment = new PathSegmentData(); + cubicSegment.command = SvgPathSegType.cubicToAbs; + cubicSegment.point1 = _mapPoint(pointTransform, point1); + cubicSegment.point2 = _mapPoint(pointTransform, point2); + cubicSegment.targetPoint = _mapPoint(pointTransform, targetPoint); + + path.cubicTo(cubicSegment.x1, cubicSegment.y1, cubicSegment.x2, + cubicSegment.y2, cubicSegment.x, cubicSegment.y); + //consumer_->EmitSegment(cubicSegment); + } + return true; + } + + Offset _mapPoint(Matrix4 transform, Offset point) { + // a, b, 0.0, 0.0, c, d, 0.0, 0.0, e, f, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 + return new Offset( + (transform[0] * point.dx + transform[4] * point.dy + transform[8]), + (transform[1] * point.dx + transform[5] * point.dy + transform[9]), + ); + } +} diff --git a/third_party/lib/src/parsers/xml_parsers.dart b/third_party/lib/src/parsers/xml_parsers.dart index 91348aa8f0a1..fea8b31fd297 100644 --- a/third_party/lib/src/parsers/xml_parsers.dart +++ b/third_party/lib/src/parsers/xml_parsers.dart @@ -15,8 +15,7 @@ Paint parseStroke(XmlElement el) { } final opacity = rawOpacity == null ? 255 - : (double.parse(rawOpacity, (source) => 1.0).clamp(0.0, 1.0) * 255) - .toInt(); + : (double.parse(rawOpacity).clamp(0.0, 1.0) * 255).toInt(); final stroke = parseColor(rawStroke).withAlpha(opacity); final rawStrokeCap = el.getAttribute('stroke-linecap'); @@ -45,7 +44,7 @@ Paint parseStroke(XmlElement el) { el.getAttribute('stroke-dasharray') != null) { print('Warning: Dash patterns not currently supported'); } - + return new Paint() ..color = stroke ..style = PaintingStyle.stroke @@ -73,8 +72,7 @@ Paint parseFill(XmlElement el, {bool isShape = true}) { } final opacity = rawOpacity == null ? 255 - : (double.parse(rawOpacity, (source) => 1.0).clamp(0.0, 1.0) * 255) - .toInt(); + : (double.parse(rawOpacity).clamp(0.0, 1.0) * 255).toInt(); final fill = parseColor(rawFill).withAlpha(opacity); return new Paint() diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 140862be8ed2..8a6150b8d672 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -1,4 +1,3 @@ -import 'dart:ui' as ui; import 'dart:async'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/src/svg_painter.dart'; diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 9aae76200688..9cee5810b7e9 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -14,7 +14,7 @@ packages: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.4.1" + version: "1.4.2" async: dependency: transitive description: @@ -28,7 +28,7 @@ packages: name: barback url: "https://pub.dartlang.org" source: hosted - version: "0.15.2+14" + version: "0.15.2+15" boolean_selector: dependency: transitive description: @@ -84,7 +84,7 @@ packages: name: cupertino_icons url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "0.1.2" flutter: dependency: "direct main" description: flutter @@ -115,7 +115,7 @@ packages: name: html url: "https://pub.dartlang.org" source: hosted - version: "0.13.2+2" + version: "0.13.3" http: dependency: transitive description: @@ -193,13 +193,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.9.6" - mockito: - dependency: transitive - description: - name: mockito - url: "https://pub.dartlang.org" - source: hosted - version: "2.2.3" multi_server_socket: dependency: transitive description: @@ -241,7 +234,7 @@ packages: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "1.7.5" + version: "1.7.6" plugin: dependency: transitive description: @@ -262,14 +255,14 @@ packages: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.3.2" + version: "1.3.6" quiver: dependency: transitive description: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "0.28.0" + version: "0.29.0+1" shelf: dependency: transitive description: @@ -358,7 +351,7 @@ packages: name: test url: "https://pub.dartlang.org" source: hosted - version: "0.12.32+1" + version: "0.12.34" typed_data: dependency: transitive description: @@ -379,7 +372,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.6" watcher: dependency: transitive description: @@ -409,4 +402,4 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.23.0 <=2.0.0-edge.0d5cf900b021bf5c9fa593ffa12b15bcd1cc5fe0" + dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.c080951d45e79cd25df98036c4be835b284a269c" diff --git a/third_party/test/path_parse_test.dart b/third_party/test/path_parse_test.dart new file mode 100644 index 000000000000..287b33d8cad1 --- /dev/null +++ b/third_party/test/path_parse_test.dart @@ -0,0 +1,68 @@ +// This is a basic Flutter widget test. +// To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter +// provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to +// find child widgets in the widget tree, read text, and verify that the values of widget properties +// are correct. + +import 'dart:ui'; +import 'package:test/test.dart'; + +import 'package:flutter_svg/src/parsers/path.dart'; + +void main() { + test('Path parse test', () { + var parser = new SvgPathStringSource('''M19.0281,19.40466 20.7195,19.40466 20.7195,15.71439 24.11486,15.71439 24.11486,14.36762 20.7195,14.36762 +20.7195,11.68641 24.74134,11.68641 24.74134,10.34618 19.0281,10.34618 z'''); + SvgPathNormalizer normalizer = new SvgPathNormalizer(); + for (PathSegmentData seg in parser.parseSegments()) { + print(seg); + normalizer.emitSegment(seg, new Path()); + } + }); + + test('Check character constants', () { + expect(AsciiConstants.slashT, '\t'.codeUnitAt(0)); + expect(AsciiConstants.slashN, '\n'.codeUnitAt(0)); + expect(AsciiConstants.slashF, '\f'.codeUnitAt(0)); + expect(AsciiConstants.slashR, '\r'.codeUnitAt(0)); + expect(AsciiConstants.space, ' '.codeUnitAt(0)); + expect(AsciiConstants.period, '.'.codeUnitAt(0)); + expect(AsciiConstants.plus, '+'.codeUnitAt(0)); + expect(AsciiConstants.comma, ','.codeUnitAt(0)); + expect(AsciiConstants.minus, '-'.codeUnitAt(0)); + expect(AsciiConstants.number0, '0'.codeUnitAt(0)); + expect(AsciiConstants.number1, '1'.codeUnitAt(0)); + expect(AsciiConstants.number2, '2'.codeUnitAt(0)); + expect(AsciiConstants.number3, '3'.codeUnitAt(0)); + expect(AsciiConstants.number4, '4'.codeUnitAt(0)); + expect(AsciiConstants.number5, '5'.codeUnitAt(0)); + expect(AsciiConstants.number6, '6'.codeUnitAt(0)); + expect(AsciiConstants.number7, '7'.codeUnitAt(0)); + expect(AsciiConstants.number8, '8'.codeUnitAt(0)); + expect(AsciiConstants.number9, '9'.codeUnitAt(0)); + expect(AsciiConstants.upperA, 'A'.codeUnitAt(0)); + expect(AsciiConstants.upperC, 'C'.codeUnitAt(0)); + expect(AsciiConstants.upperE, 'E'.codeUnitAt(0)); + expect(AsciiConstants.upperH, 'H'.codeUnitAt(0)); + expect(AsciiConstants.upperL, 'L'.codeUnitAt(0)); + expect(AsciiConstants.upperM, 'M'.codeUnitAt(0)); + expect(AsciiConstants.upperQ, 'Q'.codeUnitAt(0)); + expect(AsciiConstants.upperS, 'S'.codeUnitAt(0)); + expect(AsciiConstants.upperT, 'T'.codeUnitAt(0)); + expect(AsciiConstants.upperV, 'V'.codeUnitAt(0)); + expect(AsciiConstants.upperZ, 'Z'.codeUnitAt(0)); + expect(AsciiConstants.lowerA, 'a'.codeUnitAt(0)); + expect(AsciiConstants.lowerC, 'c'.codeUnitAt(0)); + expect(AsciiConstants.lowerE, 'e'.codeUnitAt(0)); + expect(AsciiConstants.lowerH, 'h'.codeUnitAt(0)); + expect(AsciiConstants.lowerL, 'l'.codeUnitAt(0)); + expect(AsciiConstants.lowerM, 'm'.codeUnitAt(0)); + expect(AsciiConstants.lowerQ, 'q'.codeUnitAt(0)); + expect(AsciiConstants.lowerS, 's'.codeUnitAt(0)); + expect(AsciiConstants.lowerT, 't'.codeUnitAt(0)); + expect(AsciiConstants.lowerV, 'v'.codeUnitAt(0)); + expect(AsciiConstants.lowerX, 'x'.codeUnitAt(0)); + expect(AsciiConstants.lowerZ, 'z'.codeUnitAt(0)); + expect(AsciiConstants.tilde, '~'.codeUnitAt(0)); + }); +} diff --git a/third_party/test/widget_test.dart b/third_party/test/widget_test.dart deleted file mode 100644 index 16cea800ac0c..000000000000 --- a/third_party/test/widget_test.dart +++ /dev/null @@ -1,29 +0,0 @@ -// This is a basic Flutter widget test. -// To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter -// provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to -// find child widgets in the widget tree, read text, and verify that the values of widget properties -// are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:flutter_svg/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(new MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} From 2f3858c9c4fc14c20272604a717e37a0afa2de71 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 25 Apr 2018 23:38:54 -0400 Subject: [PATCH 013/512] make analyzer happy --- third_party/lib/src/parsers/path.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/third_party/lib/src/parsers/path.dart b/third_party/lib/src/parsers/path.dart index e22bd957050e..74dca7ff15d9 100644 --- a/third_party/lib/src/parsers/path.dart +++ b/third_party/lib/src/parsers/path.dart @@ -1,7 +1,6 @@ // This code has been "translated" largely from the Chromium/blink source // for SVG path parsing. -import 'dart:async'; import 'dart:ui' show Path, Offset; import 'dart:math' show sqrt, max, pi, tan, sin, cos, pow; import 'package:vector_math/vector_math.dart' show Matrix4; From 98c0dcfef788b72c9ec25e1d579854e4c0c43e55 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 26 Apr 2018 11:24:33 -0400 Subject: [PATCH 014/512] fixes, add tiger, consume package, add license --- third_party/assets/simple/nested_group.svg | 9 + .../assets/wikimedia/Ghostscript_Tiger.svg | 725 ++++++++++++++ third_party/lib/http_test.dart | 54 ++ third_party/lib/main.dart | 17 +- third_party/lib/src/elements.dart | 45 +- third_party/lib/src/parsers/colors.dart | 1 + third_party/lib/src/parsers/path.dart | 890 ------------------ third_party/lib/src/svg_painter.dart | 9 +- third_party/lib/svg.dart | 77 +- third_party/pubspec.lock | 7 + third_party/pubspec.yaml | 3 + third_party/test/path_parse_test.dart | 68 -- 12 files changed, 926 insertions(+), 979 deletions(-) create mode 100644 third_party/assets/simple/nested_group.svg create mode 100644 third_party/assets/wikimedia/Ghostscript_Tiger.svg create mode 100644 third_party/lib/http_test.dart delete mode 100644 third_party/lib/src/parsers/path.dart delete mode 100644 third_party/test/path_parse_test.dart diff --git a/third_party/assets/simple/nested_group.svg b/third_party/assets/simple/nested_group.svg new file mode 100644 index 000000000000..33270267295a --- /dev/null +++ b/third_party/assets/simple/nested_group.svg @@ -0,0 +1,9 @@ + + + + + + + + \ No newline at end of file diff --git a/third_party/assets/wikimedia/Ghostscript_Tiger.svg b/third_party/assets/wikimedia/Ghostscript_Tiger.svg new file mode 100644 index 000000000000..679edec2eb3f --- /dev/null +++ b/third_party/assets/wikimedia/Ghostscript_Tiger.svg @@ -0,0 +1,725 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/lib/http_test.dart b/third_party/lib/http_test.dart new file mode 100644 index 000000000000..66a9ce257e2c --- /dev/null +++ b/third_party/lib/http_test.dart @@ -0,0 +1,54 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:convert'; + +const List uriNames = const [ + 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' +]; + +main() async { + uriNames.forEach((uri) async { + String ret = await loadNetworkAsset(uri, null); + print(ret); + }); +} + +Future loadNetworkAsset( + String uri, + Map headers, +) async { + final Uri resolved = Uri.base.resolve(uri); + print('trying $resolved'); + final HttpClientRequest request = await new HttpClient().getUrl(resolved); + headers?.forEach((String name, String value) { + request.headers.add(name, value); + }); + request.headers.removeAll(HttpHeaders.ACCEPT_ENCODING); + final HttpClientResponse response = await request.close(); + if (response.statusCode != HttpStatus.OK) { + throw new Exception( + 'HTTP request failed, statusCode: ${response?.statusCode}, $resolved'); + } + + final String xml = await consolidateHttpClientResponse(response); + if (xml.length == 0) + throw new Exception('NetworkImage is an empty file: $resolved'); + + return xml; +} + +Future consolidateHttpClientResponse(HttpClientResponse response) { + final Completer completer = new Completer.sync(); + final StringBuffer buffer = new StringBuffer(); + + response.transform(UTF8.decoder).listen((String chunk) { + buffer.write(chunk); + //print('CHUNK: $chunk'); + }, onDone: () { + print('DONE'); + completer.complete(buffer.toString()); + }, onError: completer.completeError, cancelOnError: true); + + return completer.future; +} diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 0df4f7b5893f..df5d5f49e0f4 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -15,7 +15,15 @@ const List assetNames = const [ 'assets/deborah_ufw/new-send-circle.svg', 'assets/deborah_ufw/numeric_25.svg', 'assets/simple/ellipse.svg', + 'assets/simple/nested_group.svg', + 'assets/wikimedia/Ghostscript_Tiger.svg', ]; + +const List uriNames = const [ + 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' +]; + void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @@ -49,11 +57,18 @@ class _MyHomePageState extends State { super.initState(); _dimension = 100.0; assetNames.forEach((assetName) { - _painters.add(new SvgImage.fromAsset( + _painters.add(new SvgImage.asset( assetName, new Size(_dimension, _dimension), )); }); + + uriNames.forEach((uri) { + _painters.add(new SvgImage.network( + uri, + new Size(_dimension, _dimension), + )); + }); } @override diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index cfee0a5d96ea..afe2b9939b77 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -1,9 +1,10 @@ import 'dart:ui'; import 'package:xml/xml.dart'; +import 'package:path_drawing/path_drawing.dart'; import 'package:vector_math/vector_math_64.dart'; + import 'parsers/parsers.dart'; -import 'parsers/path.dart'; import 'parsers/xml_parsers.dart'; typedef Path SvgPathFactory(XmlElement el); @@ -21,7 +22,7 @@ final Map _shapes = { class SvgElement { final String name; const SvgElement(this.name); - void draw(Canvas canvas) {} + void draw(Canvas canvas, [Paint parentPaint]) {} factory SvgElement.fromXml(XmlElement el) { if (el.name.local == 'g') { @@ -44,7 +45,11 @@ class SvgShape extends SvgElement { super(elementName); @override - void draw(Canvas canvas) { + void draw(Canvas canvas, [Paint parentPaint]) { + if (parentPaint != null) { + canvas.drawPath(path, parentPaint); + return; + } if (stroke != null) canvas.drawPath(path, stroke); if (fill != null) canvas.drawPath(path, fill); } @@ -60,8 +65,11 @@ class SvgShape extends SvgElement { class SvgGroup extends SvgElement { final List children; + final Paint stroke; + final Paint fill; final Matrix4 transform; - const SvgGroup(this.children, this.transform) : super('g'); + const SvgGroup(this.children, this.transform, this.stroke, this.fill) + : super('g'); factory SvgGroup.fromXml(XmlElement el) { var children = new List(); @@ -72,23 +80,36 @@ class SvgGroup extends SvgElement { }); final transform = parseTransform(el.getAttribute('transform')); + final fill = parseFill(el, isShape: false); + final stroke = parseStroke(el); return new SvgGroup( - children, - //TODO: when Dart2 is around use this instead of above - // el.children - // .whereType() - // .map((child) => new SvgBaseElement.fromXml(child)), - transform); + children, + //TODO: when Dart2 is around use this instead of above + // el.children + // .whereType() + // .map((child) => new SvgBaseElement.fromXml(child)), + transform, stroke, fill, + ); } @override - void draw(Canvas canvas) { + void draw(Canvas canvas, [Paint parentPaint]) { if (transform != null) { canvas.save(); canvas.transform(transform.storage); } - children.forEach((child) => child.draw(canvas)); + children.forEach((child) { + if (stroke != null) { + child.draw(canvas, stroke); + } + if (fill != null) { + child.draw(canvas, fill); + } + if (stroke == null && fill == null) { + child.draw(canvas); + } + }); if (transform != null) { canvas.restore(); } diff --git a/third_party/lib/src/parsers/colors.dart b/third_party/lib/src/parsers/colors.dart index 6f7f4c196d25..08206bd9a90b 100644 --- a/third_party/lib/src/parsers/colors.dart +++ b/third_party/lib/src/parsers/colors.dart @@ -35,6 +35,7 @@ Color parseColor(String colorString) { // https://www.w3.org/TR/SVG11/types.html#ColorKeywords const Map _namedColors = const { + 'none': const Color(0), 'aliceblue': const Color.fromARGB(255, 240, 248, 255), 'antiquewhite': const Color.fromARGB(255, 250, 235, 215), 'aqua': const Color.fromARGB(255, 0, 255, 255), diff --git a/third_party/lib/src/parsers/path.dart b/third_party/lib/src/parsers/path.dart deleted file mode 100644 index 74dca7ff15d9..000000000000 --- a/third_party/lib/src/parsers/path.dart +++ /dev/null @@ -1,890 +0,0 @@ -// This code has been "translated" largely from the Chromium/blink source -// for SVG path parsing. - -import 'dart:ui' show Path, Offset; -import 'dart:math' show sqrt, max, pi, tan, sin, cos, pow; -import 'package:vector_math/vector_math.dart' show Matrix4; - -const double _twoPiFloat = pi * 2.0; -const double _piOverTwoFloat = pi / 2.0; - -Path parseSvgPathData(String svg) { - final SvgPathStringSource parser = new SvgPathStringSource(svg); - final Path path = new Path(); - final SvgPathNormalizer normalizer = new SvgPathNormalizer(); - for (PathSegmentData seg in parser.parseSegments()) { - normalizer.emitSegment(seg, path); - } - return path; -} - -/// SvgPathSegType enumerates the various path segment commands. -/// -/// [AsciiConstants] houses the ASCII numeric values of these commands -enum SvgPathSegType { - /// Indicates initial state or error - unknown, - - /// Z or z - close, - - /// M - moveToAbs, - - /// m - moveToRel, - - /// L - lineToAbs, - - /// l - lineToRel, - - /// C - cubicToAbs, - - /// c - cubicToRel, - - /// Q - quadToAbs, - - /// q - quadToRel, - - /// A - arcToAbs, - - /// a - arcToRel, - - /// H - lineToHorizontalAbs, - - /// h - lineToHorizontalRel, - - /// V - lineToVerticalAbs, - - /// v - lineToVerticalRel, - - /// S - smoothCubicToAbs, - - /// s - smoothCubicToRel, - - /// T - smoothQuadToAbs, - - /// t - smoothQuadToRel -} - -/// Character constants used internally. Note that this parser does not -/// properly support non-ascii characters in the path, but it does support -/// unicode encoding. -/// -/// Only contains values that are used by the parser (does not contain the full -/// ASCII set). -class AsciiConstants { - const AsciiConstants._(); - - static SvgPathSegType mapLetterToSegmentType(int lookahead) { - return AsciiConstants.letterToSegmentType[lookahead] ?? - SvgPathSegType.unknown; - } - - /// Map to go from ASCII constant to [SvgPathSegType] - static const Map letterToSegmentType = const { - upperZ: SvgPathSegType.close, - lowerZ: SvgPathSegType.close, - upperM: SvgPathSegType.moveToAbs, - lowerM: SvgPathSegType.moveToRel, - upperL: SvgPathSegType.lineToAbs, - lowerL: SvgPathSegType.lineToRel, - upperC: SvgPathSegType.cubicToAbs, - lowerC: SvgPathSegType.cubicToRel, - upperQ: SvgPathSegType.quadToAbs, - lowerQ: SvgPathSegType.quadToRel, - upperA: SvgPathSegType.arcToAbs, - lowerA: SvgPathSegType.arcToRel, - upperH: SvgPathSegType.lineToHorizontalAbs, - lowerH: SvgPathSegType.lineToHorizontalRel, - upperV: SvgPathSegType.lineToVerticalAbs, - lowerV: SvgPathSegType.lineToVerticalRel, - upperS: SvgPathSegType.smoothCubicToAbs, - lowerS: SvgPathSegType.smoothCubicToRel, - upperT: SvgPathSegType.smoothQuadToAbs, - lowerT: SvgPathSegType.smoothQuadToRel, - }; - - /// `\t` (horizontal tab). - static const int slashT = 9; - - /// `\n` (newline). - static const int slashN = 10; - - /// `\f` (form feed). - static const int slashF = 12; - - /// `\r` (carriage return). - static const int slashR = 13; - - /// ` ` (space). - static const int space = 32; - - /// `+` (plus). - static const int plus = 43; - - /// `,` (comma). - static const int comma = 44; - - /// `-` (minus). - static const int minus = 45; - - /// `.` (period). - static const int period = 46; - - /// 0 (the number zero). - static const int number0 = 48; - - /// 1 (the number one). - static const int number1 = 49; - - /// 2 (the number two). - static const int number2 = 50; - - /// 3 (the number three). - static const int number3 = 51; - - /// 4 (the number four). - static const int number4 = 52; - - /// 5 (the number five). - static const int number5 = 53; - - /// 6 (the number six). - static const int number6 = 54; - - /// 7 (the number seven). - static const int number7 = 55; - - /// 8 (the number eight). - static const int number8 = 56; - - /// 9 (the number nine). - static const int number9 = 57; - - /// A - static const int upperA = 65; - - /// C - static const int upperC = 67; - - /// E - static const int upperE = 69; - - /// H - static const int upperH = 72; - - /// L - static const int upperL = 76; - - /// M - static const int upperM = 77; - - /// Q - static const int upperQ = 81; - - /// S - static const int upperS = 83; - - /// T - static const int upperT = 84; - - /// V - static const int upperV = 86; - - /// Z - static const int upperZ = 90; - - /// a - static const int lowerA = 97; - - /// c - static const int lowerC = 99; - - /// e - static const int lowerE = 101; - - /// h - static const int lowerH = 104; - - /// l - static const int lowerL = 108; - - /// m - static const int lowerM = 109; - - /// q - static const int lowerQ = 113; - - /// s - static const int lowerS = 115; - - /// t - static const int lowerT = 116; - - /// v - static const int lowerV = 118; - - /// x - static const int lowerX = 120; - - /// z - static const int lowerZ = 122; - - /// `~` (tilde) - static const int tilde = 126; -} - -class SvgPathStringSource { - SvgPathSegType _previousCommand; - List _codePoints; - int _idx; - - SvgPathStringSource(String string) { - assert(string != null); - _previousCommand = SvgPathSegType.unknown; - _codePoints = string.codeUnits; - _idx = 0; - _skipOptionalSvgSpaces(); - } - - bool _isHtmlSpace(int character) { - // Histogram from Apple's page load test combined with some ad hoc browsing - // some other test suites. - // - // 82%: 216330 non-space characters, all > U+0020 - // 11%: 30017 plain space characters, U+0020 - // 5%: 12099 newline characters, U+000A - // 2%: 5346 tab characters, U+0009 - // - // No other characters seen. No U+000C or U+000D, and no other control - // characters. Accordingly, we check for non-spaces first, then space, then - // newline, then tab, then the other characters. - - return character <= AsciiConstants.space && - (character == AsciiConstants.space || - character == AsciiConstants.slashN || - character == AsciiConstants.slashT || - character == AsciiConstants.slashR || - character == AsciiConstants.slashF); - } - - bool _skipOptionalSvgSpaces() { - while (_idx < _codePoints.length && _isHtmlSpace(_codePoints[_idx])) _idx++; - return _idx < _codePoints.length; - } - - bool _skipOptionalSvgSpacesOrDelimiter( - [int delimiter = AsciiConstants.comma]) { - if (_idx < _codePoints.length && - !_isHtmlSpace(_codePoints[_idx]) && - _codePoints[_idx] != delimiter) return false; - if (_skipOptionalSvgSpaces()) { - if (_idx < _codePoints.length && _codePoints[_idx] == delimiter) { - _idx++; - _skipOptionalSvgSpaces(); - } - } - return _idx < _codePoints.length; - } - - bool _isNumberStart(int lookahead) { - return (lookahead >= AsciiConstants.number0 && - lookahead <= AsciiConstants.number9) || - lookahead == AsciiConstants.plus || - lookahead == AsciiConstants.minus || - lookahead == AsciiConstants.period; - } - - SvgPathSegType _maybeImplicitCommand( - int lookahead, SvgPathSegType nextCommand) { - // Check if the current lookahead may start a number - in which case it - // could be the start of an implicit command. The 'close' command does not - // have any parameters though and hence can't have an implicit - // 'continuation'. - if (!_isNumberStart(lookahead) || _previousCommand == SvgPathSegType.close) - return nextCommand; - // Implicit continuations of moveto command translate to linetos. - if (_previousCommand == SvgPathSegType.moveToAbs) { - return SvgPathSegType.lineToAbs; - } - if (_previousCommand == SvgPathSegType.moveToRel) { - return SvgPathSegType.lineToRel; - } - return _previousCommand; - } - - bool _isValidRange(double x) { - return x >= -double.maxFinite && x <= double.maxFinite; - } - - bool _isValidExponent(double x) { - return x >= 37 && x <= 38; - } - - // We use this generic parseNumber function to allow the Path parsing code to - // work at a higher precision internally, without any unnecessary runtime cost - // or code complexity. - double _parseNumber() { - _skipOptionalSvgSpaces(); - - // read the sign - int sign = 1; - int end = _codePoints.length; - if (_idx < end && _codePoints[_idx] == AsciiConstants.plus) - _idx++; - else if (_idx < end && _codePoints[_idx] == AsciiConstants.minus) { - _idx++; - sign = -1; - } - - if (_idx == end || - ((_codePoints[_idx] < AsciiConstants.number0 || - _codePoints[_idx] > AsciiConstants.number9) && - _codePoints[_idx] != AsciiConstants.period)) - // The first character of a number must be one of [0-9+-.] - throw new StateError( - 'First character of a number must be one of [0-9+-.]'); - - // read the integer part, build right-to-left - final int digitsStart = _idx; - while (_idx < end && - _codePoints[_idx] >= AsciiConstants.number0 && - _codePoints[_idx] <= AsciiConstants.number9) - ++_idx; // Advance to first non-digit. - - double integer = 0.0; - if (_idx != digitsStart) { - int ptrScanIntPart = _idx - 1; - int multiplier = 1; - while (ptrScanIntPart >= digitsStart) { - integer += multiplier * - (_codePoints[ptrScanIntPart--] - AsciiConstants.number0); - - multiplier *= 10; - } - // Bail out early if this overflows. - if (!_isValidRange(integer)) throw new StateError('Numeric overflow'); - } - - double decimal = 0.0; - if (_idx < end && _codePoints[_idx] == AsciiConstants.period) { - // read the decimals - _idx++; - - // There must be a least one digit following the . - if (_idx >= end || - _codePoints[_idx] < AsciiConstants.number0 || - _codePoints[_idx] > AsciiConstants.number9) - throw new StateError( - 'There must be at least one digit following the .'); - - double frac = 1.0; - while (_idx < end && - _codePoints[_idx] >= AsciiConstants.number0 && - _codePoints[_idx] <= AsciiConstants.number9) { - frac *= 0.1; - decimal += (_codePoints[_idx++] - AsciiConstants.number0) * frac; - } - } - - // When we get here we should have consumed either a digit for the integer - // part or a fractional part (with at least one digit after the '.'.) - assert(digitsStart != _idx); - - double number = integer + decimal; - number *= sign; - - // read the exponent part - if (_idx + 1 < end && - (_codePoints[_idx] == AsciiConstants.lowerE || - _codePoints[_idx] == AsciiConstants.upperE) && - (_codePoints[_idx + 1] != AsciiConstants.lowerX && - _codePoints[_idx + 1] != AsciiConstants.lowerM)) { - _idx++; - - // read the sign of the exponent - bool exponentIsNegative = false; - if (_codePoints[_idx] == AsciiConstants.plus) - _idx++; - else if (_codePoints[_idx] == AsciiConstants.minus) { - _idx++; - exponentIsNegative = true; - } - - // There must be an exponent - if (_idx >= end || - _codePoints[_idx] < AsciiConstants.number0 || - _codePoints[_idx] > AsciiConstants.number9) - throw new StateError('Missing exponent'); - - double exponent = 0.0; - while (_idx < end && - _codePoints[_idx] >= AsciiConstants.number0 && - _codePoints[_idx] <= AsciiConstants.number9) { - exponent *= 10.0; - exponent += _codePoints[_idx] - AsciiConstants.number0; - _idx++; - } - if (exponentIsNegative) exponent = -exponent; - // Make sure exponent is valid. - if (!_isValidExponent(exponent)) throw new StateError('Invalid exponent'); - if (exponent != 0) number *= pow(10.0, exponent); - } - - // Don't return Infinity() or NaN(). - if (!_isValidRange(number)) throw new StateError('Numeric overflow'); - - // if (mode & kAllowTrailingWhitespace) - _skipOptionalSvgSpacesOrDelimiter(); - - return number; - } - - bool _parseArcFlag() { - if (!hasMoreData) throw new StateError('Expected more data'); - final int flagChar = _codePoints[_idx]; - _idx++; - _skipOptionalSvgSpacesOrDelimiter(); - - if (flagChar == AsciiConstants.number0) - return false; - else if (flagChar == AsciiConstants.number1) - return true; - else - throw new StateError('Invalid flag value'); - } - - bool get hasMoreData => _idx < _codePoints.length; - - Iterable parseSegments() sync* { - while (hasMoreData) { - yield parseSegment(); - } - } - - PathSegmentData parseSegment() { - assert(hasMoreData); - PathSegmentData segment = new PathSegmentData(); - int lookahead = _codePoints[_idx]; - SvgPathSegType command = AsciiConstants.mapLetterToSegmentType(lookahead); - if (_previousCommand == SvgPathSegType.unknown) { - // First command has to be a moveto. - if (command != SvgPathSegType.moveToRel && - command != SvgPathSegType.moveToAbs) { - throw new StateError('Expected to find moveTo command'); - // SetErrorMark(SVGParseStatus::kExpectedMoveToCommand); - // return segment; - } - // Consume command letter. - _idx++; - } else if (command == SvgPathSegType.unknown) { - // Possibly an implicit command. - assert(_previousCommand != SvgPathSegType.unknown); - command = _maybeImplicitCommand(lookahead, command); - if (command == null || command == SvgPathSegType.unknown) { - throw new StateError('Expected a path command'); - } - } else { - // Valid explicit command. - _idx++; - } - - segment.command = _previousCommand = command; - - switch (segment.command) { - case SvgPathSegType.cubicToRel: - case SvgPathSegType.cubicToAbs: - segment.point1 = new Offset(_parseNumber(), _parseNumber()); - continue cubic_smooth; - case SvgPathSegType.smoothCubicToRel: - cubic_smooth: - case SvgPathSegType.smoothCubicToAbs: - segment.point2 = new Offset(_parseNumber(), _parseNumber()); - continue quad_smooth; - case SvgPathSegType.moveToRel: - case SvgPathSegType.moveToAbs: - case SvgPathSegType.lineToRel: - case SvgPathSegType.lineToAbs: - case SvgPathSegType.smoothQuadToRel: - quad_smooth: - case SvgPathSegType.smoothQuadToAbs: - segment.targetPoint = new Offset(_parseNumber(), _parseNumber()); - break; - case SvgPathSegType.lineToHorizontalRel: - case SvgPathSegType.lineToHorizontalAbs: - segment.targetPoint = - new Offset(_parseNumber(), segment.targetPoint?.dy ?? 0.0); - break; - case SvgPathSegType.lineToVerticalRel: - case SvgPathSegType.lineToVerticalAbs: - segment.targetPoint = - new Offset(segment.targetPoint?.dx ?? 0.0, _parseNumber()); - break; - case SvgPathSegType.close: - _skipOptionalSvgSpaces(); - break; - case SvgPathSegType.quadToRel: - case SvgPathSegType.quadToAbs: - segment.point1 = new Offset(_parseNumber(), _parseNumber()); - segment.targetPoint = new Offset(_parseNumber(), _parseNumber()); - - break; - case SvgPathSegType.arcToRel: - case SvgPathSegType.arcToAbs: - segment.point1 = new Offset(_parseNumber(), _parseNumber()); - segment.arcAngle = _parseNumber(); - segment.arcLarge = _parseArcFlag(); - segment.arcSweep = _parseArcFlag(); - segment.targetPoint = new Offset(_parseNumber(), _parseNumber()); - break; - case SvgPathSegType.unknown: - throw new StateError('Unknown segment command'); - } - - return segment; - } -} - -class OffsetHelper { - static Offset reflectedPoint(Offset reflectedIn, Offset pointToReflect) { - return new Offset(2 * reflectedIn.dx - pointToReflect.dx, - 2 * reflectedIn.dy - pointToReflect.dy); - } - - static const double _kOneOverThree = 1.0 / 3.0; - - /// Blend the points with a ratio (1/3):(2/3). - static Offset blendPoints(Offset p1, Offset p2) { - return Offset((p1.dx + 2 * p2.dx) * _kOneOverThree, - (p1.dy + 2 * p2.dy) * _kOneOverThree); - } -} - -bool isCubicCommand(SvgPathSegType command) { - return command == SvgPathSegType.cubicToAbs || - command == SvgPathSegType.cubicToRel || - command == SvgPathSegType.smoothCubicToAbs || - command == SvgPathSegType.smoothCubicToRel; -} - -bool isQuadraticCommand(SvgPathSegType command) { - return command == SvgPathSegType.quadToAbs || - command == SvgPathSegType.quadToRel || - command == SvgPathSegType.smoothQuadToAbs || - command == SvgPathSegType.smoothQuadToRel; -} - -class PathSegmentData { - PathSegmentData() - : command = SvgPathSegType.unknown, - arcSweep = false, - arcLarge = false; - - Offset get arcRadii => point1; - - double get arcAngle => point2.dx; - set arcAngle(double angle) => point2 = new Offset(angle, point2.dy); - - double get r1 => arcRadii.dx; - double get r2 => arcRadii.dy; - - bool get largeArcFlag => arcLarge; - bool get sweepFlag => arcSweep; - - double get x => targetPoint.dx; - double get y => targetPoint.dy; - - double get x1 => point1.dx; - double get y1 => point1.dy; - - double get x2 => point2.dx; - double get y2 => point2.dy; - - SvgPathSegType command; - Offset targetPoint; - Offset point1; - Offset point2; - bool arcSweep; - bool arcLarge; - - @override - String toString() { - return 'PathSegmentData{$command $targetPoint $point1 $point2 $arcSweep $arcLarge}'; - } -} - -class SvgPathNormalizer { - Offset _currentPoint = Offset.zero; - Offset _subPathPoint = Offset.zero; - Offset _controlPoint = Offset.zero; - SvgPathSegType _lastCommand = SvgPathSegType.unknown; - - void emitSegment(PathSegmentData segment, Path path) { - PathSegmentData normSeg = segment; - assert( - normSeg.command == SvgPathSegType.close || normSeg.targetPoint != null); - assert(_currentPoint != null); - // Convert relative points to absolute points. - switch (segment.command) { - case SvgPathSegType.quadToRel: - normSeg.point1 += _currentPoint; - normSeg.targetPoint += _currentPoint; - break; - case SvgPathSegType.cubicToRel: - normSeg.point1 += _currentPoint; - continue smooth_rel; - smooth_rel: - case SvgPathSegType.smoothCubicToRel: - normSeg.point2 += _currentPoint; - continue arc_rel; - case SvgPathSegType.moveToRel: - case SvgPathSegType.lineToRel: - case SvgPathSegType.lineToHorizontalRel: - case SvgPathSegType.lineToVerticalRel: - case SvgPathSegType.smoothQuadToRel: - arc_rel: - case SvgPathSegType.arcToRel: - normSeg.targetPoint += _currentPoint; - break; - case SvgPathSegType.lineToHorizontalAbs: - normSeg.targetPoint = - new Offset(normSeg.targetPoint.dx, _currentPoint.dy); - break; - case SvgPathSegType.lineToVerticalAbs: - normSeg.targetPoint = - new Offset(_currentPoint.dx, normSeg.targetPoint.dy); - break; - case SvgPathSegType.close: - // Reset m_currentPoint for the next path. - normSeg.targetPoint = _subPathPoint; - break; - default: - break; - } - - // Update command verb, handle smooth segments and convert quadratic curve - // segments to cubics. - switch (segment.command) { - case SvgPathSegType.moveToRel: - case SvgPathSegType.moveToAbs: - _subPathPoint = normSeg.targetPoint; - normSeg.command = SvgPathSegType.moveToAbs; - path.moveTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy); - break; - case SvgPathSegType.lineToRel: - case SvgPathSegType.lineToAbs: - case SvgPathSegType.lineToHorizontalRel: - case SvgPathSegType.lineToHorizontalAbs: - case SvgPathSegType.lineToVerticalRel: - case SvgPathSegType.lineToVerticalAbs: - normSeg.command = SvgPathSegType.lineToAbs; - path.lineTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy); - break; - case SvgPathSegType.close: - normSeg.command = SvgPathSegType.close; - path.close(); - break; - case SvgPathSegType.smoothCubicToRel: - case SvgPathSegType.smoothCubicToAbs: - if (!isCubicCommand(_lastCommand)) - normSeg.point1 = _currentPoint; - else - normSeg.point1 = - OffsetHelper.reflectedPoint(_currentPoint, _controlPoint); - continue cubic_abs2; - case SvgPathSegType.cubicToRel: - cubic_abs2: - case SvgPathSegType.cubicToAbs: - _controlPoint = normSeg.point2; - normSeg.command = SvgPathSegType.cubicToAbs; - path.cubicTo(normSeg.point1.dx, normSeg.point1.dy, normSeg.point2.dx, - normSeg.point2.dy, normSeg.targetPoint.dx, normSeg.targetPoint.dy); - break; - case SvgPathSegType.smoothQuadToRel: - case SvgPathSegType.smoothQuadToAbs: - if (!isQuadraticCommand(_lastCommand)) - normSeg.point1 = _currentPoint; - else - normSeg.point1 = - OffsetHelper.reflectedPoint(_currentPoint, _controlPoint); - continue quad_abs2; - case SvgPathSegType.quadToRel: - quad_abs2: - case SvgPathSegType.quadToAbs: - // Save the unmodified control point. - _controlPoint = normSeg.point1; - normSeg.point1 = OffsetHelper.blendPoints(_currentPoint, _controlPoint); - normSeg.point2 = - OffsetHelper.blendPoints(normSeg.targetPoint, _controlPoint); - normSeg.command = SvgPathSegType.cubicToAbs; - path.cubicTo(normSeg.point1.dx, normSeg.point1.dy, normSeg.point2.dx, - normSeg.point2.dy, normSeg.targetPoint.dx, normSeg.targetPoint.dy); - break; - case SvgPathSegType.arcToRel: - case SvgPathSegType.arcToAbs: - if (!_decomposeArcToCubic(_currentPoint, normSeg, path)) { - // On failure, emit a line segment to the target point. - normSeg.command = SvgPathSegType.lineToAbs; - path.lineTo(normSeg.targetPoint.dx, normSeg.targetPoint.dy); - } else { - // decomposeArcToCubic() has already emitted the normalized - // segments, so set command to PathSegArcAbs, to skip any further - // emit. - normSeg.command = SvgPathSegType.arcToAbs; - } - break; - default: - throw new StateError('Invalid command type in path'); - } - - // if (normSeg.command != SvgPathSegType.arcToAbs) { - // - // //consumer_.EmitSegment(normSeg); - // } - - _currentPoint = normSeg.targetPoint; - - if (!isCubicCommand(segment.command) && - !isQuadraticCommand(segment.command)) { - _controlPoint = _currentPoint; - } - - _lastCommand = segment.command; - } - -// This works by converting the SVG arc to "simple" beziers. -// Partly adapted from Niko's code in kdelibs/kdecore/svgicons. -// See also SVG implementation notes: -// http://www.w3.org/TR/SVG/implnote.html#ArcConversionEndpointToCenter - bool _decomposeArcToCubic( - Offset currentPoint, PathSegmentData arcSegment, Path path) { - // If rx = 0 or ry = 0 then this arc is treated as a straight line segment (a - // "lineto") joining the endpoints. - // http://www.w3.org/TR/SVG/implnote.html#ArcOutOfRangeParameters - double rx = arcSegment.arcRadii.dx.abs(); - double ry = arcSegment.arcRadii.dy.abs(); - if (rx == 0 || ry == 0) { - return false; - } - - // If the current point and target point for the arc are identical, it should - // be treated as a zero length path. This ensures continuity in animations. - if (arcSegment.targetPoint == currentPoint) { - return false; - } - - double angle = arcSegment.arcAngle; - - Offset midPointDistance = currentPoint - arcSegment.targetPoint; - midPointDistance.scale(0.5, 0.5); - - Matrix4 pointTransform = new Matrix4.identity(); - pointTransform.rotateZ(-angle); - - Offset transformedMidPoint = _mapPoint( - pointTransform, Offset(midPointDistance.dx, midPointDistance.dy)); - double squareRx = rx * rx; - double squareRy = ry * ry; - double squareX = transformedMidPoint.dx * transformedMidPoint.dx; - double squareY = transformedMidPoint.dy * transformedMidPoint.dy; - - // Check if the radii are big enough to draw the arc, scale radii if not. - // http://www.w3.org/TR/SVG/implnote.html#ArcCorrectionOutOfRangeRadii - double radiiScale = squareX / squareRx + squareY / squareRy; - if (radiiScale > 1) { - rx *= sqrt(radiiScale); - ry *= sqrt(radiiScale); - } - - pointTransform.setIdentity(); - pointTransform.scale(1 / rx, 1 / ry); - pointTransform.rotateZ(-angle); - - Offset point1 = _mapPoint(pointTransform, currentPoint); - Offset point2 = _mapPoint(pointTransform, arcSegment.targetPoint); - Offset delta = point2 - point1; - - double d = delta.dx * delta.dx + delta.dy * delta.dy; - double scaleFactorSquared = max(1 / d - 0.25, 0.0); - - double scaleFactor = sqrt(scaleFactorSquared); - if (arcSegment.arcSweep == arcSegment.arcLarge) scaleFactor = -scaleFactor; - - delta.scale(scaleFactor, scaleFactor); - Offset centerPoint = point1 + point2; - centerPoint.scale(0.5, 0.5); - centerPoint.translate(-delta.dx, delta.dy); - - double theta1 = (point1 - centerPoint).direction; - double theta2 = (point2 - centerPoint).direction; - - double thetaArc = theta2 - theta1; - if (thetaArc < 0 && arcSegment.arcSweep) - thetaArc += _twoPiFloat; - else if (thetaArc > 0 && !arcSegment.arcSweep) thetaArc -= _twoPiFloat; - - pointTransform.setIdentity(); - pointTransform.rotateZ(angle); - pointTransform.scale(rx, ry); - - // Some results of atan2 on some platform implementations are not exact - // enough. So that we get more cubic curves than expected here. Adding 0.001f - // reduces the count of sgements to the correct count. - final int segments = (thetaArc / (_piOverTwoFloat + 0.001)).abs().ceil(); - for (int i = 0; i < segments; ++i) { - final double startTheta = theta1 + i * thetaArc / segments; - final double endTheta = theta1 + (i + 1) * thetaArc / segments; - - final double t = (8 / 6.0) * tan(0.25 * (endTheta - startTheta)); - if (!t.isFinite) return false; - final double sinStartTheta = sin(startTheta); - final double cosStartTheta = cos(startTheta); - final double sinEndTheta = sin(endTheta); - final double cosEndTheta = cos(endTheta); - - point1 = Offset( - cosStartTheta - t * sinStartTheta, sinStartTheta + t * cosStartTheta); - point1.translate(centerPoint.dx, centerPoint.dy); - final Offset targetPoint = new Offset(cosEndTheta, sinEndTheta); - targetPoint.translate(centerPoint.dx, centerPoint.dy); - point2 = targetPoint; - point2.translate(t * sinEndTheta, -t * cosEndTheta); - - final PathSegmentData cubicSegment = new PathSegmentData(); - cubicSegment.command = SvgPathSegType.cubicToAbs; - cubicSegment.point1 = _mapPoint(pointTransform, point1); - cubicSegment.point2 = _mapPoint(pointTransform, point2); - cubicSegment.targetPoint = _mapPoint(pointTransform, targetPoint); - - path.cubicTo(cubicSegment.x1, cubicSegment.y1, cubicSegment.x2, - cubicSegment.y2, cubicSegment.x, cubicSegment.y); - //consumer_->EmitSegment(cubicSegment); - } - return true; - } - - Offset _mapPoint(Matrix4 transform, Offset point) { - // a, b, 0.0, 0.0, c, d, 0.0, 0.0, e, f, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 - return new Offset( - (transform[0] * point.dx + transform[4] * point.dy + transform[8]), - (transform[1] * point.dx + transform[5] * point.dy + transform[9]), - ); - } -} diff --git a/third_party/lib/src/svg_painter.dart b/third_party/lib/src/svg_painter.dart index 1e33c380f45f..ec4b562c0e20 100644 --- a/third_party/lib/src/svg_painter.dart +++ b/third_party/lib/src/svg_painter.dart @@ -6,8 +6,10 @@ import 'package:flutter_svg/src/elements.dart'; class SvgPainter extends CustomPainter { final XmlDocument _rawSvg; + final bool _clipToViewBox; - SvgPainter(this._rawSvg); + SvgPainter(this._rawSvg, {bool clipToViewBox = true}) + : _clipToViewBox = clipToViewBox; @override void paint(Canvas canvas, Size size) { @@ -17,6 +19,11 @@ class SvgPainter extends CustomPainter { final vbRect = parseViewBox(viewBox); canvas.scale( size.width / vbRect.size.width, size.height / vbRect.size.height); + + if (_clipToViewBox) { + canvas.clipRect(vbRect); + } + for (var el in _rawSvg.rootElement.children) { if (el is! XmlElement) continue; final svgEl = new SvgElement.fromXml(el); diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 8a6150b8d672..334d3f950206 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -1,19 +1,35 @@ import 'dart:async'; +import 'dart:io'; +import 'dart:convert'; + +import 'package:flutter/services.dart' show rootBundle, AssetBundle; import 'package:flutter/widgets.dart'; + import 'package:flutter_svg/src/svg_painter.dart'; -import 'package:flutter/services.dart' show rootBundle; import 'package:xml/xml.dart'; class SvgImage extends StatelessWidget { final Size size; final Future future; + final bool clipToViewBox; + + const SvgImage._(this.future, this.size, {this.clipToViewBox = true, Key key}) + : super(key: key); - const SvgImage._(this.future, this.size, {Key key}) : super(key: key); + factory SvgImage.asset(String assetName, Size size, + {Key key, AssetBundle bundle, String package}) { + return new SvgImage._( + loadAsset(assetName, bundle, package), + size, + key: key, + ); + } - factory SvgImage.fromAsset(String assetName, Size size, {Key key}) { + factory SvgImage.network(String uri, Size size, + {Map headers, Key key}) { return new SvgImage._( - loadAsset(assetName), + loadNetworkAsset(uri, headers), size, key: key, ); @@ -25,7 +41,9 @@ class SvgImage extends StatelessWidget { builder: ((context, snapShot) { if (snapShot.hasData) { return new CustomPaint( - painter: new SvgPainter(snapShot.data), size: size); + painter: + new SvgPainter(snapShot.data, clipToViewBox: clipToViewBox), + size: size); } return new LimitedBox(); }), @@ -33,7 +51,52 @@ class SvgImage extends StatelessWidget { } } -Future loadAsset(String assetName) async { - final xml = await rootBundle.loadString(assetName); +Future loadAsset(String assetName, + [AssetBundle bundle, String package]) async { + bundle ??= rootBundle; + final xml = await bundle + .loadString(package == null ? assetName : 'packages/$package/$assetName'); return parse(xml); } + +final HttpClient _httpClient = new HttpClient(); + +Future loadNetworkAsset( + String uri, + Map headers, +) async { + final Uri resolved = Uri.base.resolve(uri); + print('trying $resolved'); + final HttpClientRequest request = await _httpClient.getUrl(resolved); + headers?.forEach((String name, String value) { + request.headers.add(name, value); + }); + request.headers.removeAll(HttpHeaders.ACCEPT_ENCODING); + final HttpClientResponse response = await request.close(); + if (response.statusCode != HttpStatus.OK) { + throw new Exception( + 'HTTP request failed, statusCode: ${response?.statusCode}, $resolved'); + } + + final String xml = await consolidateHttpClientResponse(response); + if (xml.length == 0) + throw new Exception('NetworkImage is an empty file: $resolved'); + + print('$resolved headers: ${response.headers}'); + print(xml); + assert(xml.endsWith('')); + return parse(xml); +} + +Future consolidateHttpClientResponse(HttpClientResponse response) { + final Completer completer = new Completer.sync(); + final StringBuffer buffer = new StringBuffer(); + + response.transform(utf8.decoder).listen((String chunk) { + buffer.write(chunk); + }, onDone: () { + completer.complete(buffer.toString()); + }, onError: completer.completeError, cancelOnError: true); + + return completer.future; +} diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 9cee5810b7e9..e06b745d49bd 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -228,6 +228,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.5.1" + path_drawing: + dependency: "direct main" + description: + name: path_drawing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.0" petitparser: dependency: transitive description: diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index c3c907e09c43..41ea846465f0 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,6 +2,7 @@ name: flutter_svg description: A new Flutter project. dependencies: + path_drawing: ^0.1.0 xml: any vector_math: any flutter: @@ -42,6 +43,8 @@ flutter: - assets/deborah_ufw/new-send-circle.svg - assets/deborah_ufw/numeric_25.svg - assets/simple/ellipse.svg + - assets/simple/nested_group.svg + - assets/wikimedia/Ghostscript_Tiger.svg # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg diff --git a/third_party/test/path_parse_test.dart b/third_party/test/path_parse_test.dart deleted file mode 100644 index 287b33d8cad1..000000000000 --- a/third_party/test/path_parse_test.dart +++ /dev/null @@ -1,68 +0,0 @@ -// This is a basic Flutter widget test. -// To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter -// provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to -// find child widgets in the widget tree, read text, and verify that the values of widget properties -// are correct. - -import 'dart:ui'; -import 'package:test/test.dart'; - -import 'package:flutter_svg/src/parsers/path.dart'; - -void main() { - test('Path parse test', () { - var parser = new SvgPathStringSource('''M19.0281,19.40466 20.7195,19.40466 20.7195,15.71439 24.11486,15.71439 24.11486,14.36762 20.7195,14.36762 -20.7195,11.68641 24.74134,11.68641 24.74134,10.34618 19.0281,10.34618 z'''); - SvgPathNormalizer normalizer = new SvgPathNormalizer(); - for (PathSegmentData seg in parser.parseSegments()) { - print(seg); - normalizer.emitSegment(seg, new Path()); - } - }); - - test('Check character constants', () { - expect(AsciiConstants.slashT, '\t'.codeUnitAt(0)); - expect(AsciiConstants.slashN, '\n'.codeUnitAt(0)); - expect(AsciiConstants.slashF, '\f'.codeUnitAt(0)); - expect(AsciiConstants.slashR, '\r'.codeUnitAt(0)); - expect(AsciiConstants.space, ' '.codeUnitAt(0)); - expect(AsciiConstants.period, '.'.codeUnitAt(0)); - expect(AsciiConstants.plus, '+'.codeUnitAt(0)); - expect(AsciiConstants.comma, ','.codeUnitAt(0)); - expect(AsciiConstants.minus, '-'.codeUnitAt(0)); - expect(AsciiConstants.number0, '0'.codeUnitAt(0)); - expect(AsciiConstants.number1, '1'.codeUnitAt(0)); - expect(AsciiConstants.number2, '2'.codeUnitAt(0)); - expect(AsciiConstants.number3, '3'.codeUnitAt(0)); - expect(AsciiConstants.number4, '4'.codeUnitAt(0)); - expect(AsciiConstants.number5, '5'.codeUnitAt(0)); - expect(AsciiConstants.number6, '6'.codeUnitAt(0)); - expect(AsciiConstants.number7, '7'.codeUnitAt(0)); - expect(AsciiConstants.number8, '8'.codeUnitAt(0)); - expect(AsciiConstants.number9, '9'.codeUnitAt(0)); - expect(AsciiConstants.upperA, 'A'.codeUnitAt(0)); - expect(AsciiConstants.upperC, 'C'.codeUnitAt(0)); - expect(AsciiConstants.upperE, 'E'.codeUnitAt(0)); - expect(AsciiConstants.upperH, 'H'.codeUnitAt(0)); - expect(AsciiConstants.upperL, 'L'.codeUnitAt(0)); - expect(AsciiConstants.upperM, 'M'.codeUnitAt(0)); - expect(AsciiConstants.upperQ, 'Q'.codeUnitAt(0)); - expect(AsciiConstants.upperS, 'S'.codeUnitAt(0)); - expect(AsciiConstants.upperT, 'T'.codeUnitAt(0)); - expect(AsciiConstants.upperV, 'V'.codeUnitAt(0)); - expect(AsciiConstants.upperZ, 'Z'.codeUnitAt(0)); - expect(AsciiConstants.lowerA, 'a'.codeUnitAt(0)); - expect(AsciiConstants.lowerC, 'c'.codeUnitAt(0)); - expect(AsciiConstants.lowerE, 'e'.codeUnitAt(0)); - expect(AsciiConstants.lowerH, 'h'.codeUnitAt(0)); - expect(AsciiConstants.lowerL, 'l'.codeUnitAt(0)); - expect(AsciiConstants.lowerM, 'm'.codeUnitAt(0)); - expect(AsciiConstants.lowerQ, 'q'.codeUnitAt(0)); - expect(AsciiConstants.lowerS, 's'.codeUnitAt(0)); - expect(AsciiConstants.lowerT, 't'.codeUnitAt(0)); - expect(AsciiConstants.lowerV, 'v'.codeUnitAt(0)); - expect(AsciiConstants.lowerX, 'x'.codeUnitAt(0)); - expect(AsciiConstants.lowerZ, 'z'.codeUnitAt(0)); - expect(AsciiConstants.tilde, '~'.codeUnitAt(0)); - }); -} From 7547a38b39e12a00b1c7d5d88ea2bab21237b422 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 26 Apr 2018 12:26:21 -0400 Subject: [PATCH 015/512] fix transform bug, comment out network for now --- third_party/lib/main.dart | 4 ++-- third_party/lib/src/parsers/parsers.dart | 2 +- third_party/lib/src/svg_painter.dart | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index df5d5f49e0f4..e890502489b4 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -20,8 +20,8 @@ const List assetNames = const [ ]; const List uriNames = const [ - 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' + // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' ]; void main() => runApp(new MyApp()); diff --git a/third_party/lib/src/parsers/parsers.dart b/third_party/lib/src/parsers/parsers.dart index eba7e28cfea9..d13875ef8040 100644 --- a/third_party/lib/src/parsers/parsers.dart +++ b/third_party/lib/src/parsers/parsers.dart @@ -117,5 +117,5 @@ Matrix4 _parseSvgRotate(String paramsStr, Matrix4 current) { Matrix4 _matrix(double a, double b, double c, double d, double e, double f) { return new Matrix4( - a, b, 0.0, 0.0, c, d, 0.0, 0.0, e, f, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); + a, b, 0.0, 0.0, c, d, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, e, f, 0.0, 1.0); } diff --git a/third_party/lib/src/svg_painter.dart b/third_party/lib/src/svg_painter.dart index ec4b562c0e20..dd650041cbac 100644 --- a/third_party/lib/src/svg_painter.dart +++ b/third_party/lib/src/svg_painter.dart @@ -23,7 +23,6 @@ class SvgPainter extends CustomPainter { if (_clipToViewBox) { canvas.clipRect(vbRect); } - for (var el in _rawSvg.rootElement.children) { if (el is! XmlElement) continue; final svgEl = new SvgElement.fromXml(el); From 086a0a0b3abab814854ea4c49b23032a298532bc Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 26 Apr 2018 12:27:45 -0400 Subject: [PATCH 016/512] update path ver --- third_party/pubspec.lock | 2 +- third_party/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index e06b745d49bd..4eedc4a3ed4a 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -234,7 +234,7 @@ packages: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.1.0" + version: "0.1.1" petitparser: dependency: transitive description: diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 41ea846465f0..01cc1a8eefe3 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: A new Flutter project. dependencies: - path_drawing: ^0.1.0 + path_drawing: ^0.1.1 xml: any vector_math: any flutter: From f49f887e184d4c4db4131717655cdd6da6ef8fa3 Mon Sep 17 00:00:00 2001 From: fmatosqg Date: Fri, 27 Apr 2018 14:22:43 +1000 Subject: [PATCH 017/512] Update pubspec.yaml Enforce flutter version is >= 0.3.5 --- third_party/pubspec.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 01cc1a8eefe3..ec151a912a54 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -73,3 +73,6 @@ flutter: # # For details regarding fonts from package dependencies, # see https://flutter.io/custom-fonts/#from-packages + +environment: + flutter: ">=0.3.5 <2.0.0" From 843fe520de7ff8c172997ab081c3b9aee871c53c Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 27 Apr 2018 01:01:55 -0400 Subject: [PATCH 018/512] travis --- third_party/travis.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 third_party/travis.yml diff --git a/third_party/travis.yml b/third_party/travis.yml new file mode 100644 index 000000000000..08860728a43f --- /dev/null +++ b/third_party/travis.yml @@ -0,0 +1,19 @@ +os: + - linux +sudo: false +addons: + apt: + # Flutter depends on /usr/lib/x86_64-linux-gnu/libstdc++.so.6 version GLIBCXX_3.4.18 + sources: + - ubuntu-toolchain-r-test # if we don't specify this, the libstdc++6 we get is the wrong version + packages: + - libstdc++6 + - fonts-droid +before_script: + - git clone https://github.com/dnfield/flutter_svg.git -b beta + - ./flutter/bin/flutter doctor +script: + - ./flutter/bin/flutter test +cache: + directories: + - $HOME/.pub-cache \ No newline at end of file From 7baa65d8203d296ebe924260d85744f71d848f3b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 27 Apr 2018 01:03:56 -0400 Subject: [PATCH 019/512] fix travis.yml --- third_party/travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/travis.yml b/third_party/travis.yml index 08860728a43f..d13f731cdf4d 100644 --- a/third_party/travis.yml +++ b/third_party/travis.yml @@ -10,7 +10,7 @@ addons: - libstdc++6 - fonts-droid before_script: - - git clone https://github.com/dnfield/flutter_svg.git -b beta + - git clone https://github.com/flutter/flutter.git -b beta - ./flutter/bin/flutter doctor script: - ./flutter/bin/flutter test From 8ec7690dc5c03d7b235d83257c4a6530fdf6be33 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 28 Apr 2018 08:25:38 -0400 Subject: [PATCH 020/512] support RRects, minor refactoring, gradients WIP --- third_party/assets/flutter_logo.svg | 3 + third_party/assets/simple/linear_gradient.svg | 11 +++ .../assets/simple/linear_gradient_2.svg | 24 ++++++ third_party/assets/simple/rect_rrect.svg | 4 + third_party/lib/main.dart | 59 ++++++++------- third_party/lib/src/elements.dart | 45 +++++++---- third_party/lib/src/parsers/colors.dart | 1 + third_party/lib/src/parsers/xml_parsers.dart | 45 ++++++++++- third_party/lib/src/svg_painter.dart | 37 +++++++--- third_party/lib/svg.dart | 46 ++++-------- third_party/pubspec.lock | 2 +- third_party/pubspec.yaml | 6 +- third_party/test/network_test.dart | 74 +++++++++++++++++++ 13 files changed, 270 insertions(+), 87 deletions(-) create mode 100644 third_party/assets/flutter_logo.svg create mode 100644 third_party/assets/simple/linear_gradient.svg create mode 100644 third_party/assets/simple/linear_gradient_2.svg create mode 100644 third_party/assets/simple/rect_rrect.svg create mode 100644 third_party/test/network_test.dart diff --git a/third_party/assets/flutter_logo.svg b/third_party/assets/flutter_logo.svg new file mode 100644 index 000000000000..8dd18b3a51c4 --- /dev/null +++ b/third_party/assets/flutter_logo.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/third_party/assets/simple/linear_gradient.svg b/third_party/assets/simple/linear_gradient.svg new file mode 100644 index 000000000000..c1d492339ac3 --- /dev/null +++ b/third_party/assets/simple/linear_gradient.svg @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/third_party/assets/simple/linear_gradient_2.svg b/third_party/assets/simple/linear_gradient_2.svg new file mode 100644 index 000000000000..eb75d36c2646 --- /dev/null +++ b/third_party/assets/simple/linear_gradient_2.svg @@ -0,0 +1,24 @@ + + + + Example lingrad01 - fill a rectangle using a + linear gradient paint server + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/assets/simple/rect_rrect.svg b/third_party/assets/simple/rect_rrect.svg new file mode 100644 index 000000000000..b1b5eb015da8 --- /dev/null +++ b/third_party/assets/simple/rect_rrect.svg @@ -0,0 +1,4 @@ + + + + diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index e890502489b4..51888b18040b 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -2,26 +2,30 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; const List assetNames = const [ - 'assets/w3samples/aa.svg', - 'assets/w3samples/alphachannel.svg', - 'assets/deborah_ufw/new-action-expander.svg', - 'assets/deborah_ufw/new-camera.svg', - 'assets/deborah_ufw/new-gif-button.svg', - 'assets/deborah_ufw/new-gif.svg', - 'assets/deborah_ufw/new-image.svg', - 'assets/deborah_ufw/new-mention.svg', - 'assets/deborah_ufw/new-pause-button.svg', - 'assets/deborah_ufw/new-play-button.svg', - 'assets/deborah_ufw/new-send-circle.svg', - 'assets/deborah_ufw/numeric_25.svg', - 'assets/simple/ellipse.svg', - 'assets/simple/nested_group.svg', - 'assets/wikimedia/Ghostscript_Tiger.svg', + //'assets/flutter_logo.svg', + 'assets/simple/linear_gradient.svg', + 'assets/simple/linear_gradient_2.svg', + // 'assets/simple/rect_rrect.svg', + // 'assets/w3samples/aa.svg', + // 'assets/w3samples/alphachannel.svg', + // 'assets/deborah_ufw/new-action-expander.svg', + // 'assets/deborah_ufw/new-camera.svg', + // 'assets/deborah_ufw/new-gif-button.svg', + // 'assets/deborah_ufw/new-gif.svg', + // 'assets/deborah_ufw/new-image.svg', + // 'assets/deborah_ufw/new-mention.svg', + // 'assets/deborah_ufw/new-pause-button.svg', + // 'assets/deborah_ufw/new-play-button.svg', + // 'assets/deborah_ufw/new-send-circle.svg', + // 'assets/deborah_ufw/numeric_25.svg', + // 'assets/simple/ellipse.svg', + // 'assets/simple/nested_group.svg', + // 'assets/wikimedia/Ghostscript_Tiger.svg', ]; const List uriNames = const [ - // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' + 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' ]; void main() => runApp(new MyApp()); @@ -57,17 +61,21 @@ class _MyHomePageState extends State { super.initState(); _dimension = 100.0; assetNames.forEach((assetName) { - _painters.add(new SvgImage.asset( - assetName, - new Size(_dimension, _dimension), - )); + _painters.add( + new SvgImage.asset( + assetName, + new Size(_dimension, _dimension), + ), + ); }); uriNames.forEach((uri) { - _painters.add(new SvgImage.network( - uri, - new Size(_dimension, _dimension), - )); + _painters.add( + new SvgImage.network( + uri, + new Size(_dimension, _dimension), + ), + ); }); } @@ -83,6 +91,7 @@ class _MyHomePageState extends State { max: MediaQuery.of(context).size.width - 10.0, value: _dimension, onChanged: (val) => setState(() => _dimension = val)), + new FlutterLogo(size: _dimension), new Expanded( child: new GridView.extent( shrinkWrap: true, diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index afe2b9939b77..966407b15be0 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -11,7 +11,6 @@ typedef Path SvgPathFactory(XmlElement el); final Map _shapes = { 'circle': (el) => pathFromSvgCircle(el), 'path': (el) => pathFromSvgPath(el), - //'g': (el) => new SvgGroup.fromXml(el), 'rect': (el) => pathFromSvgRect(el), 'polygon': (el) => pathFromSvgPolygonOrLine(el), 'polyline': (el) => pathFromSvgPolygonOrLine(el), @@ -24,14 +23,13 @@ class SvgElement { const SvgElement(this.name); void draw(Canvas canvas, [Paint parentPaint]) {} - factory SvgElement.fromXml(XmlElement el) { + factory SvgElement.fromXml(XmlElement el, Map paintServers) { if (el.name.local == 'g') { - return new SvgGroup.fromXml(el); + return new SvgGroup.fromXml(el, paintServers); } else if (_shapes.containsKey(el.name.local)) { - return new SvgShape.fromXml(el); - } else { - return new SvgElement(el.name.local); + return new SvgShape.fromXml(el, paintServers); } + return new SvgElement(el.name.local); } } @@ -54,9 +52,9 @@ class SvgShape extends SvgElement { if (fill != null) canvas.drawPath(path, fill); } - factory SvgShape.fromXml(XmlElement el) { + factory SvgShape.fromXml(XmlElement el, Map paintServers) { final stroke = parseStroke(el); - final fill = parseFill(el); + final fill = parseFill(el, paintServers); final ret = _shapes[el.name.local]; return new SvgShape(ret(el), stroke, fill, el.name.local); @@ -71,16 +69,19 @@ class SvgGroup extends SvgElement { const SvgGroup(this.children, this.transform, this.stroke, this.fill) : super('g'); - factory SvgGroup.fromXml(XmlElement el) { + factory SvgGroup.fromXml(XmlElement el, Map paintServers) { var children = new List(); el.children.forEach((child) { if (child is XmlElement) { - children.add(new SvgElement.fromXml(child)); + final SvgElement el = new SvgElement.fromXml(child, paintServers); + if (el != null) { + children.add(el); + } } }); final transform = parseTransform(el.getAttribute('transform')); - final fill = parseFill(el, isShape: false); + final fill = parseFill(el, paintServers, isShape: false); final stroke = parseStroke(el); return new SvgGroup( @@ -146,12 +147,24 @@ Path pathFromSvgPath(XmlElement el) { } Path pathFromSvgRect(XmlElement el) { - final x = double.parse(el.getAttribute('x')); - final y = double.parse(el.getAttribute('y')); - final w = double.parse(el.getAttribute('width')); - final h = double.parse(el.getAttribute('height')); + final double x = double.parse(el.getAttribute('x')); + final double y = double.parse(el.getAttribute('y')); + final double w = double.parse(el.getAttribute('width')); + final double h = double.parse(el.getAttribute('height')); + final Rect rect = new Rect.fromLTWH(x, y, w, h); + String rxRaw = el.getAttribute('rx'); + String ryRaw = el.getAttribute('ry'); + rxRaw ??= ryRaw; + ryRaw ??= rxRaw; + + if ((rxRaw != null && rxRaw != "")) { + final double rx = double.parse(rxRaw); + final double ry = double.parse(ryRaw); + return transformPath( + new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)), el); + } - final path = new Path()..addRect(new Rect.fromLTWH(x, y, w, h)); + final path = new Path()..addRect(rect); return transformPath(path, el); } diff --git a/third_party/lib/src/parsers/colors.dart b/third_party/lib/src/parsers/colors.dart index 08206bd9a90b..64c4cd868d55 100644 --- a/third_party/lib/src/parsers/colors.dart +++ b/third_party/lib/src/parsers/colors.dart @@ -6,6 +6,7 @@ Color parseColor(String colorString) { if (colorString == null || colorString.length == 0) { return const Color.fromARGB(255, 0, 0, 0); } + if (colorString[0] == '#') { if (colorString.length == 4) { final r = colorString[1]; diff --git a/third_party/lib/src/parsers/xml_parsers.dart b/third_party/lib/src/parsers/xml_parsers.dart index fea8b31fd297..2044d044db10 100644 --- a/third_party/lib/src/parsers/xml_parsers.dart +++ b/third_party/lib/src/parsers/xml_parsers.dart @@ -3,6 +3,43 @@ import 'dart:ui'; import 'package:flutter_svg/src/parsers/colors.dart'; import 'package:xml/xml.dart'; +void parseDefs(XmlElement el, Map paintServers) { + el.children.forEach((XmlNode def) { + if (def is XmlElement) { + if (def.name.local.endsWith('Gradient')) { + paintServers['url(#${def.getAttribute('id')})'] = parseGradient(def); + } + } + }); +} + +Paint parseGradient(XmlElement el) { + if (el.name.local == 'linearGradient') { + final Gradient gradient = new Gradient.linear( + new Offset( + double.parse(el.getAttribute('x1')?.substring(1) ?? '0'), + double.parse(el.getAttribute('x2')?.substring(1) ?? '100'), + ), + new Offset( + double.parse(el.getAttribute('y1')?.substring(1) ?? '0'), + double.parse(el.getAttribute('y2')?.substring(1) ?? '0'), + ), + el.findElements('stop').map((stop) { + return parseColor(stop.getAttribute('stop-color')).withAlpha( + (double.parse(stop.getAttribute('stop-opacity') ?? '1') * 255) + .toInt()); + }).toList(), + // el.findElements('stop').map((stop) { + // String rawOffset = stop.getAttribute('offset'); + // return double.parse('.' + rawOffset.substring(0, rawOffset.length - 1)); + // }).toList(), + ); + + return new Paint()..shader = gradient; + } else if (el.name.local == 'radialGradient') {} + throw new StateError('Unknown gradient type ${el.name.local}'); +} + Paint parseStroke(XmlElement el) { final rawStroke = el.getAttribute('stroke'); if (rawStroke == null || rawStroke.length == 0) { @@ -54,7 +91,8 @@ Paint parseStroke(XmlElement el) { ..strokeMiterLimit = miterLimit; } -Paint parseFill(XmlElement el, {bool isShape = true}) { +Paint parseFill(XmlElement el, Map paintServers, + {bool isShape = true}) { final rawFill = el.getAttribute('fill'); if (rawFill == null || rawFill.length == 0) { if (isShape) { @@ -66,6 +104,10 @@ Paint parseFill(XmlElement el, {bool isShape = true}) { } } + if (rawFill.startsWith('url')) { + return paintServers[rawFill]; + } + var rawOpacity = el.getAttribute('fill-opacity'); if (rawOpacity == null) { rawOpacity = el.getAttribute('opacity'); @@ -73,6 +115,7 @@ Paint parseFill(XmlElement el, {bool isShape = true}) { final opacity = rawOpacity == null ? 255 : (double.parse(rawOpacity).clamp(0.0, 1.0) * 255).toInt(); + final fill = parseColor(rawFill).withAlpha(opacity); return new Paint() diff --git a/third_party/lib/src/svg_painter.dart b/third_party/lib/src/svg_painter.dart index dd650041cbac..a8006a03f1ed 100644 --- a/third_party/lib/src/svg_painter.dart +++ b/third_party/lib/src/svg_painter.dart @@ -1,33 +1,48 @@ import 'package:xml/xml.dart'; import 'package:flutter/widgets.dart'; -import 'package:flutter_svg/src/parsers/parsers.dart'; import 'package:flutter_svg/src/elements.dart'; +import 'package:flutter_svg/src/parsers/parsers.dart'; +import 'package:flutter_svg/src/parsers/xml_parsers.dart'; class SvgPainter extends CustomPainter { - final XmlDocument _rawSvg; + final _rawSvg; final bool _clipToViewBox; - SvgPainter(this._rawSvg, {bool clipToViewBox = true}) - : _clipToViewBox = clipToViewBox; + SvgPainter(String rawSvg, {bool clipToViewBox = true}) + : _rawSvg = parse(rawSvg), + _clipToViewBox = clipToViewBox; @override void paint(Canvas canvas, Size size) { if (_rawSvg == null) return; - var viewBox = _rawSvg.rootElement.getAttribute('viewBox'); + final String viewBox = _rawSvg.rootElement.getAttribute('viewBox') ?? + '0 0 ' + '${_rawSvg.rootElement.getAttribute('width') ?? '0'} ' + '${_rawSvg.rootElement.getAttribute('height') ?? '0'}'; + final vbRect = parseViewBox(viewBox); canvas.scale( - size.width / vbRect.size.width, size.height / vbRect.size.height); - + size.width / vbRect.size.width, + size.height / vbRect.size.height, + ); + if (_clipToViewBox) { - canvas.clipRect(vbRect); + canvas.clipRect(vbRect.translate(vbRect.left, vbRect.top)); } + final Map paintServers = {}; + for (var el in _rawSvg.rootElement.children) { - if (el is! XmlElement) continue; - final svgEl = new SvgElement.fromXml(el); - svgEl.draw(canvas); + if (el is XmlElement) { + if (el.name.local == 'defs') { + parseDefs(el, paintServers); + } else { + new SvgElement.fromXml(el, paintServers).draw(canvas); + } + } } + print(paintServers); } @override diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 334d3f950206..acac0fa96c27 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -7,11 +7,9 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_svg/src/svg_painter.dart'; -import 'package:xml/xml.dart'; - class SvgImage extends StatelessWidget { final Size size; - final Future future; + final Future future; final bool clipToViewBox; const SvgImage._(this.future, this.size, {this.clipToViewBox = true, Key key}) @@ -29,7 +27,7 @@ class SvgImage extends StatelessWidget { factory SvgImage.network(String uri, Size size, {Map headers, Key key}) { return new SvgImage._( - loadNetworkAsset(uri, headers), + loadNetworkAsset2(uri), size, key: key, ); @@ -51,50 +49,34 @@ class SvgImage extends StatelessWidget { } } -Future loadAsset(String assetName, +Future loadAsset(String assetName, [AssetBundle bundle, String package]) async { bundle ??= rootBundle; - final xml = await bundle + return await bundle .loadString(package == null ? assetName : 'packages/$package/$assetName'); - return parse(xml); } final HttpClient _httpClient = new HttpClient(); -Future loadNetworkAsset( - String uri, - Map headers, -) async { - final Uri resolved = Uri.base.resolve(uri); - print('trying $resolved'); - final HttpClientRequest request = await _httpClient.getUrl(resolved); - headers?.forEach((String name, String value) { - request.headers.add(name, value); - }); - request.headers.removeAll(HttpHeaders.ACCEPT_ENCODING); +Future loadNetworkAsset2(String url) async { + final Uri uri = Uri.base.resolve(url); + print('trying $uri'); + final HttpClientRequest request = await _httpClient.getUrl(uri); final HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.OK) { - throw new Exception( - 'HTTP request failed, statusCode: ${response?.statusCode}, $resolved'); - } - - final String xml = await consolidateHttpClientResponse(response); - if (xml.length == 0) - throw new Exception('NetworkImage is an empty file: $resolved'); - - print('$resolved headers: ${response.headers}'); - print(xml); - assert(xml.endsWith('')); - return parse(xml); + print(response.statusCode); + if (response.statusCode != HttpStatus.OK) throw new FlutterError('Could not get network SVG asset'); + return await consolidateHttpClientResponse(response); } -Future consolidateHttpClientResponse(HttpClientResponse response) { +Future consolidateHttpClientResponse( + HttpClientResponse response) async { final Completer completer = new Completer.sync(); final StringBuffer buffer = new StringBuffer(); response.transform(utf8.decoder).listen((String chunk) { buffer.write(chunk); }, onDone: () { + print(buffer.toString()); completer.complete(buffer.toString()); }, onError: completer.completeError, cancelOnError: true); diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 4eedc4a3ed4a..fae2281a1d14 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -409,4 +409,4 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.c080951d45e79cd25df98036c4be835b284a269c" + dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.0d5cf900b021bf5c9fa593ffa12b15bcd1cc5fe0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index ec151a912a54..2a705a0d571e 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -3,7 +3,7 @@ description: A new Flutter project. dependencies: path_drawing: ^0.1.1 - xml: any + xml: ^3.0.0 vector_math: any flutter: sdk: flutter @@ -30,6 +30,7 @@ flutter: # To add assets to your application, add an assets section, like this: assets: + - assets/flutter_logo.svg - assets/w3samples/alphachannel.svg - assets/w3samples/aa.svg - assets/deborah_ufw/new-action-expander.svg @@ -44,6 +45,9 @@ flutter: - assets/deborah_ufw/numeric_25.svg - assets/simple/ellipse.svg - assets/simple/nested_group.svg + - assets/simple/rect_rrect.svg + - assets/simple/linear_gradient.svg + - assets/simple/linear_gradient_2.svg - assets/wikimedia/Ghostscript_Tiger.svg # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg diff --git a/third_party/test/network_test.dart b/third_party/test/network_test.dart new file mode 100644 index 000000000000..891b3e5f7937 --- /dev/null +++ b/third_party/test/network_test.dart @@ -0,0 +1,74 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:convert'; + +import 'package:flutter/services.dart'; +import 'package:test/test.dart'; + +void main() { + test('GZIP', () async { + String svg = await loadNetworkAsset2( + 'https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg'); + expect(svg, ''' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +'''); + }); +} + +Future loadNetworkAsset(String uri) async { + final NetworkAssetBundle _network = + new NetworkAssetBundle(Uri.base.resolve(uri)); + return await _network.loadString(uri); +} + +Future loadNetworkAsset2(String url) async { + final HttpClientRequest request = + await new HttpClient().getUrl(Uri.base.resolve(url)); + final HttpClientResponse response = await request.close(); + if (response.statusCode != HttpStatus.OK) throw new Error(); + return await consolidateHttpClientResponse(response); +} + +Future consolidateHttpClientResponse( + HttpClientResponse response) async { + final Completer completer = new Completer.sync(); + final StringBuffer buffer = new StringBuffer(); + + response.transform(utf8.decoder).listen((String chunk) { + buffer.write(chunk); + }, onDone: () { + completer.complete(buffer.toString()); + }, onError: completer.completeError, cancelOnError: true); + + return completer.future; +} From abda74357453fc832aa7fd511e318a04b13389aa Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 28 Apr 2018 11:58:49 -0400 Subject: [PATCH 021/512] gradients better, but scaling wrong --- third_party/assets/flutter_logo.svg | 31 ++- third_party/lib/main.dart | 8 +- third_party/lib/src/elements.dart | 212 ++++++++++--------- third_party/lib/src/gradients.dart | 3 + third_party/lib/src/parsers/xml_parsers.dart | 130 +++++++----- third_party/lib/src/svg_painter.dart | 15 +- third_party/lib/svg.dart | 7 +- third_party/pubspec.lock | 1 + third_party/test/xml_test.dart | 23 ++ 9 files changed, 264 insertions(+), 166 deletions(-) create mode 100644 third_party/lib/src/gradients.dart create mode 100644 third_party/test/xml_test.dart diff --git a/third_party/assets/flutter_logo.svg b/third_party/assets/flutter_logo.svg index 8dd18b3a51c4..8c19aa227f1c 100644 --- a/third_party/assets/flutter_logo.svg +++ b/third_party/assets/flutter_logo.svg @@ -1,3 +1,32 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 51888b18040b..1a7908190b41 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -2,7 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; const List assetNames = const [ - //'assets/flutter_logo.svg', + 'assets/flutter_logo.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', // 'assets/simple/rect_rrect.svg', @@ -24,8 +24,8 @@ const List assetNames = const [ ]; const List uriNames = const [ - 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' + // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' ]; void main() => runApp(new MyApp()); @@ -91,7 +91,7 @@ class _MyHomePageState extends State { max: MediaQuery.of(context).size.width - 10.0, value: _dimension, onChanged: (val) => setState(() => _dimension = val)), - new FlutterLogo(size: _dimension), + //new FlutterLogo(size: _dimension), new Expanded( child: new GridView.extent( shrinkWrap: true, diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart index 966407b15be0..bf932619a286 100644 --- a/third_party/lib/src/elements.dart +++ b/third_party/lib/src/elements.dart @@ -4,30 +4,122 @@ import 'package:xml/xml.dart'; import 'package:path_drawing/path_drawing.dart'; import 'package:vector_math/vector_math_64.dart'; +import 'gradients.dart'; import 'parsers/parsers.dart'; import 'parsers/xml_parsers.dart'; -typedef Path SvgPathFactory(XmlElement el); +typedef SvgShapeInfo SvgPathFactory(XmlElement el); final Map _shapes = { - 'circle': (el) => pathFromSvgCircle(el), - 'path': (el) => pathFromSvgPath(el), - 'rect': (el) => pathFromSvgRect(el), - 'polygon': (el) => pathFromSvgPolygonOrLine(el), - 'polyline': (el) => pathFromSvgPolygonOrLine(el), - 'ellipse': (el) => pathFromSvgEllipse(el), - 'line': (el) => pathFromSvgLine(el), + 'circle': (el) => new SvgShapeInfo.fromSvgCircle(el), + 'path': (el) => new SvgShapeInfo.fromSvgPath(el), + 'rect': (el) => new SvgShapeInfo.fromSvgRect(el), + 'polygon': (el) => new SvgShapeInfo.fromSvgPolygonOrLine(el), + 'polyline': (el) => new SvgShapeInfo.fromSvgPolygonOrLine(el), + 'ellipse': (el) => new SvgShapeInfo.fromSvgEllipse(el), + 'line': (el) => new SvgShapeInfo.fromSvgLine(el), }; + +class SvgShapeInfo { + const SvgShapeInfo(this.path, this.size); + final Path path; + final Size size; + + static Path transformPath(Path path, XmlElement el) { + assert(path != null); + assert(el != null); + + final transform = parseTransform(el.getAttribute('transform')); + + if (transform != null) { + return path.transform(transform.storage); + } else { + return path; + } + } + + factory SvgShapeInfo.fromSvgCircle(XmlElement el) { + final cx = double.parse(el.getAttribute('cx')); + final cy = double.parse(el.getAttribute('cy')); + final r = double.parse(el.getAttribute('r')); + final oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); + final path = new Path()..addOval(oval); + return new SvgShapeInfo(transformPath(path, el), oval.size); + } + + factory SvgShapeInfo.fromSvgPath(XmlElement el) { + final d = el.getAttribute('d'); + final Path p = parseSvgPathData(d); + return new SvgShapeInfo(transformPath(p, el), p.getBounds().size); + } + + factory SvgShapeInfo.fromSvgRect(XmlElement el) { + final double x = double.parse(el.getAttribute('x')); + final double y = double.parse(el.getAttribute('y')); + final double w = double.parse(el.getAttribute('width')); + final double h = double.parse(el.getAttribute('height')); + final Rect rect = new Rect.fromLTWH(x, y, w, h); + String rxRaw = el.getAttribute('rx'); + String ryRaw = el.getAttribute('ry'); + rxRaw ??= ryRaw; + ryRaw ??= rxRaw; + + if ((rxRaw != null && rxRaw != "")) { + final double rx = double.parse(rxRaw); + final double ry = double.parse(ryRaw); + return new SvgShapeInfo( + transformPath( + new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)), el), + rect.size, + ); + } + + final path = new Path()..addRect(rect); + return new SvgShapeInfo(transformPath(path, el), rect.size); + } + + factory SvgShapeInfo.fromSvgPolygonOrLine(XmlElement el) { + final path = parseSvgPathData('M' + el.getAttribute('points') + 'z'); + + return SvgShapeInfo(transformPath(path, el), path.getBounds().size); + } + + factory SvgShapeInfo.fromSvgEllipse(XmlElement el) { + final cx = double.parse(el.getAttribute('cx')); + final cy = double.parse(el.getAttribute('cy')); + final rx = double.parse(el.getAttribute('rx')); + final ry = double.parse(el.getAttribute('ry')); + + Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); + + return new SvgShapeInfo(transformPath(new Path()..addOval(r), el), r.size); + } + + factory SvgShapeInfo.fromSvgLine(XmlElement el) { + final x1 = double.parse(el.getAttribute('x1')); + final x2 = double.parse(el.getAttribute('x2')); + final y1 = double.parse(el.getAttribute('y1')); + final y2 = double.parse(el.getAttribute('y2')); + + final path = new Path() + ..moveTo(x1, x2) + ..lineTo(y1, y2); + return new SvgShapeInfo(transformPath(path, el), path.getBounds().size); + } +} class SvgElement { final String name; const SvgElement(this.name); void draw(Canvas canvas, [Paint parentPaint]) {} - factory SvgElement.fromXml(XmlElement el, Map paintServers) { - if (el.name.local == 'g') { - return new SvgGroup.fromXml(el, paintServers); + factory SvgElement.fromXml( + XmlElement el, Map paintServers, Size size) { + if (el.name.local == 'defs') { + parseDefs(el, paintServers, size); + } else if (el.name.local == 'g') { + return new SvgGroup.fromXml(el, paintServers, size); } else if (_shapes.containsKey(el.name.local)) { - return new SvgShape.fromXml(el, paintServers); + return new SvgShape.fromXml(el, paintServers, size); } return new SvgElement(el.name.local); } @@ -52,12 +144,13 @@ class SvgShape extends SvgElement { if (fill != null) canvas.drawPath(path, fill); } - factory SvgShape.fromXml(XmlElement el, Map paintServers) { + factory SvgShape.fromXml( + XmlElement el, Map paintServers, Size size) { + final ret = _shapes[el.name.local](el); final stroke = parseStroke(el); - final fill = parseFill(el, paintServers); - final ret = _shapes[el.name.local]; + final fill = parseFill(el, ret.size, paintServers); - return new SvgShape(ret(el), stroke, fill, el.name.local); + return new SvgShape(ret.path, stroke, fill, el.name.local); } } @@ -69,11 +162,12 @@ class SvgGroup extends SvgElement { const SvgGroup(this.children, this.transform, this.stroke, this.fill) : super('g'); - factory SvgGroup.fromXml(XmlElement el, Map paintServers) { + factory SvgGroup.fromXml( + XmlElement el, Map paintServers, Size size) { var children = new List(); el.children.forEach((child) { if (child is XmlElement) { - final SvgElement el = new SvgElement.fromXml(child, paintServers); + final SvgElement el = new SvgElement.fromXml(child, paintServers, size); if (el != null) { children.add(el); } @@ -81,7 +175,7 @@ class SvgGroup extends SvgElement { }); final transform = parseTransform(el.getAttribute('transform')); - final fill = parseFill(el, paintServers, isShape: false); + final fill = parseFill(el, size, paintServers, isShape: false); final stroke = parseStroke(el); return new SvgGroup( @@ -116,83 +210,3 @@ class SvgGroup extends SvgElement { } } } - -Path transformPath(Path path, XmlElement el) { - assert(path != null); - assert(el != null); - - final transform = parseTransform(el.getAttribute('transform')); - - if (transform != null) { - return path.transform(transform.storage); - } else { - return path; - } -} - -Path pathFromSvgCircle(XmlElement el) { - final cx = double.parse(el.getAttribute('cx')); - final cy = double.parse(el.getAttribute('cy')); - final r = double.parse(el.getAttribute('r')); - - final path = new Path() - ..addOval(new Rect.fromCircle(center: new Offset(cx, cy), radius: r)); - return transformPath(path, el); -} - -Path pathFromSvgPath(XmlElement el) { - final d = el.getAttribute('d'); - final Path p = parseSvgPathData(d); - return transformPath(p, el); -} - -Path pathFromSvgRect(XmlElement el) { - final double x = double.parse(el.getAttribute('x')); - final double y = double.parse(el.getAttribute('y')); - final double w = double.parse(el.getAttribute('width')); - final double h = double.parse(el.getAttribute('height')); - final Rect rect = new Rect.fromLTWH(x, y, w, h); - String rxRaw = el.getAttribute('rx'); - String ryRaw = el.getAttribute('ry'); - rxRaw ??= ryRaw; - ryRaw ??= rxRaw; - - if ((rxRaw != null && rxRaw != "")) { - final double rx = double.parse(rxRaw); - final double ry = double.parse(ryRaw); - return transformPath( - new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)), el); - } - - final path = new Path()..addRect(rect); - return transformPath(path, el); -} - -Path pathFromSvgPolygonOrLine(XmlElement el) { - final path = parseSvgPathData('M' + el.getAttribute('points') + 'z'); - - return transformPath(path, el); -} - -Path pathFromSvgEllipse(XmlElement el) { - final cx = double.parse(el.getAttribute('cx')); - final cy = double.parse(el.getAttribute('cy')); - final rx = double.parse(el.getAttribute('rx')); - final ry = double.parse(el.getAttribute('ry')); - - Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); - - return transformPath(new Path()..addOval(r), el); -} - -Path pathFromSvgLine(XmlElement el) { - final x1 = double.parse(el.getAttribute('x1')); - final x2 = double.parse(el.getAttribute('x2')); - final y1 = double.parse(el.getAttribute('y1')); - final y2 = double.parse(el.getAttribute('y2')); - - final path = new Path() - ..moveTo(x1, x2) - ..lineTo(y1, y2); - return transformPath(path, el); -} diff --git a/third_party/lib/src/gradients.dart b/third_party/lib/src/gradients.dart new file mode 100644 index 000000000000..e65f21269ce6 --- /dev/null +++ b/third_party/lib/src/gradients.dart @@ -0,0 +1,3 @@ +import 'dart:ui'; + +typedef Paint PaintServer(Size size); \ No newline at end of file diff --git a/third_party/lib/src/parsers/xml_parsers.dart b/third_party/lib/src/parsers/xml_parsers.dart index 2044d044db10..599c9b5020d8 100644 --- a/third_party/lib/src/parsers/xml_parsers.dart +++ b/third_party/lib/src/parsers/xml_parsers.dart @@ -1,84 +1,112 @@ import 'dart:ui'; -import 'package:flutter_svg/src/parsers/colors.dart'; import 'package:xml/xml.dart'; -void parseDefs(XmlElement el, Map paintServers) { +import '../gradients.dart'; +import 'colors.dart'; + +void parseDefs( + XmlElement el, Map paintServers, Size size) { el.children.forEach((XmlNode def) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { - paintServers['url(#${def.getAttribute('id')})'] = parseGradient(def); + paintServers['url(#${def.getAttribute('id')})'] = + (size) => parseGradient(def, size); } } }); } -Paint parseGradient(XmlElement el) { +/// Gets the attribute, trims it, and returns the attribute or default if the attribute +/// is null or "" +String _getAttribute(XmlElement el, String name, [String def = ""]) { + final String raw = el.getAttribute(name)?.trim(); + return raw == "" || raw == null ? def : raw; +} + +double _parseDecimalOrPercentage(String val) { + if (val.endsWith('%')) { + return double.parse(val.substring(0, val.length - 1)) / 100; + } else { + return double.parse(val); + } +} + + + +Paint parseLinearGradient(XmlElement el, Size size) { + final double x1 = _parseDecimalOrPercentage(_getAttribute(el, 'x1', '0%')); + final double x2 = _parseDecimalOrPercentage(_getAttribute(el, 'x2', '100%')); + final double y1 = _parseDecimalOrPercentage(_getAttribute(el, 'y1', '0%')); + final double y2 = _parseDecimalOrPercentage(_getAttribute(el, 'y2', '0%')); + + final Offset from = new Offset(size.width * x1, size.height * y1); + final Offset to = new Offset(size.width * x2, size.height * y2); + print('$size $from $to'); + final stops = el.findElements('stop').toList(); + final Gradient gradient = new Gradient.linear( + from, + to, + stops.map((stop) { + return parseColor(_getAttribute(stop, 'stop-color')).withAlpha( + (double.parse(_getAttribute(stop, 'stop-opacity', '1')).clamp(0, 1) * + 255) + .toInt()); + }).toList(), + stops.map((stop) { + String rawOffset = _getAttribute(stop, 'offset'); + return _parseDecimalOrPercentage(rawOffset); + }).toList(), + ); + + return new Paint()..shader = gradient; +} + +Paint parseGradient(XmlElement el, Size size) { if (el.name.local == 'linearGradient') { - final Gradient gradient = new Gradient.linear( - new Offset( - double.parse(el.getAttribute('x1')?.substring(1) ?? '0'), - double.parse(el.getAttribute('x2')?.substring(1) ?? '100'), - ), - new Offset( - double.parse(el.getAttribute('y1')?.substring(1) ?? '0'), - double.parse(el.getAttribute('y2')?.substring(1) ?? '0'), - ), - el.findElements('stop').map((stop) { - return parseColor(stop.getAttribute('stop-color')).withAlpha( - (double.parse(stop.getAttribute('stop-opacity') ?? '1') * 255) - .toInt()); - }).toList(), - // el.findElements('stop').map((stop) { - // String rawOffset = stop.getAttribute('offset'); - // return double.parse('.' + rawOffset.substring(0, rawOffset.length - 1)); - // }).toList(), - ); - - return new Paint()..shader = gradient; + return parseLinearGradient(el, size); } else if (el.name.local == 'radialGradient') {} throw new StateError('Unknown gradient type ${el.name.local}'); } Paint parseStroke(XmlElement el) { - final rawStroke = el.getAttribute('stroke'); - if (rawStroke == null || rawStroke.length == 0) { + final rawStroke = _getAttribute(el, 'stroke'); + if (rawStroke == "") { return null; } - var rawOpacity = el.getAttribute('stroke-opacity'); - if (rawOpacity == null) { - rawOpacity = el.getAttribute('opacity'); + var rawOpacity = _getAttribute(el, 'stroke-opacity'); + if (rawOpacity == "") { + rawOpacity = _getAttribute(el, 'opacity'); } - final opacity = rawOpacity == null + final opacity = rawOpacity == "" ? 255 : (double.parse(rawOpacity).clamp(0.0, 1.0) * 255).toInt(); final stroke = parseColor(rawStroke).withAlpha(opacity); - final rawStrokeCap = el.getAttribute('stroke-linecap'); - StrokeCap strokeCap = rawStrokeCap == null + final rawStrokeCap = _getAttribute(el, 'stroke-linecap'); + StrokeCap strokeCap = rawStrokeCap == "null" ? StrokeCap.butt : StrokeCap.values.firstWhere( (sc) => sc.toString() == 'StrokeCap.$rawStrokeCap', orElse: () => StrokeCap.butt); - final rawLineJoin = el.getAttribute('stroke-linejoin'); - StrokeJoin strokeJoin = rawLineJoin == null + final rawLineJoin = _getAttribute(el, 'stroke-linejoin'); + StrokeJoin strokeJoin = rawLineJoin == "" ? StrokeJoin.miter : StrokeJoin.values.firstWhere( (sj) => sj.toString() == 'StrokeJoin.$rawLineJoin', orElse: () => StrokeJoin.miter); - final rawMiterLimit = el.getAttribute('stroke-miterlimit'); - final miterLimit = rawMiterLimit == null ? 4.0 : double.parse(rawMiterLimit); + final rawMiterLimit = _getAttribute(el, 'stroke-miterlimit'); + final miterLimit = rawMiterLimit == "" ? 4.0 : double.parse(rawMiterLimit); - final rawStrokeWidth = el.getAttribute('stroke-width'); - final strokeWidth = - rawStrokeWidth == null ? 1.0 : double.parse(rawStrokeWidth); + final rawStrokeWidth = _getAttribute(el, 'stroke-width'); + final strokeWidth = rawStrokeWidth == "" ? 1.0 : double.parse(rawStrokeWidth); // TODO: Dash patterns not currently supported - if (el.getAttribute('stroke-dashoffset') != null || - el.getAttribute('stroke-dasharray') != null) { + if (_getAttribute(el, 'stroke-dashoffset') != "" || + _getAttribute(el, 'stroke-dasharray') != "") { print('Warning: Dash patterns not currently supported'); } @@ -91,10 +119,10 @@ Paint parseStroke(XmlElement el) { ..strokeMiterLimit = miterLimit; } -Paint parseFill(XmlElement el, Map paintServers, +Paint parseFill(XmlElement el, Size size, Map paintServers, {bool isShape = true}) { - final rawFill = el.getAttribute('fill'); - if (rawFill == null || rawFill.length == 0) { + final rawFill = _getAttribute(el, 'fill'); + if (rawFill == "") { if (isShape) { return new Paint() ..color = colorBlack @@ -105,15 +133,15 @@ Paint parseFill(XmlElement el, Map paintServers, } if (rawFill.startsWith('url')) { - return paintServers[rawFill]; + return paintServers[rawFill](size); } - var rawOpacity = el.getAttribute('fill-opacity'); - if (rawOpacity == null) { - rawOpacity = el.getAttribute('opacity'); + var rawOpacity = _getAttribute(el, 'fill-opacity'); + if (rawOpacity == "") { + rawOpacity = _getAttribute(el, 'opacity'); } - final opacity = rawOpacity == null - ? 255 + final opacity = rawOpacity == "" + ? rawFill == 'none' ? 0 : 255 : (double.parse(rawOpacity).clamp(0.0, 1.0) * 255).toInt(); final fill = parseColor(rawFill).withAlpha(opacity); diff --git a/third_party/lib/src/svg_painter.dart b/third_party/lib/src/svg_painter.dart index a8006a03f1ed..8f9b17c1a265 100644 --- a/third_party/lib/src/svg_painter.dart +++ b/third_party/lib/src/svg_painter.dart @@ -1,9 +1,11 @@ import 'package:xml/xml.dart'; import 'package:flutter/widgets.dart'; -import 'package:flutter_svg/src/elements.dart'; -import 'package:flutter_svg/src/parsers/parsers.dart'; -import 'package:flutter_svg/src/parsers/xml_parsers.dart'; +import 'elements.dart'; +import 'gradients.dart'; +import 'parsers/parsers.dart'; +import 'parsers/xml_parsers.dart'; + class SvgPainter extends CustomPainter { final _rawSvg; @@ -31,18 +33,17 @@ class SvgPainter extends CustomPainter { if (_clipToViewBox) { canvas.clipRect(vbRect.translate(vbRect.left, vbRect.top)); } - final Map paintServers = {}; + final Map paintServers = {}; for (var el in _rawSvg.rootElement.children) { if (el is XmlElement) { if (el.name.local == 'defs') { - parseDefs(el, paintServers); + parseDefs(el, paintServers, size); } else { - new SvgElement.fromXml(el, paintServers).draw(canvas); + new SvgElement.fromXml(el, paintServers, size).draw(canvas); } } } - print(paintServers); } @override diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index acac0fa96c27..fc5d49244150 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -5,7 +5,7 @@ import 'dart:convert'; import 'package:flutter/services.dart' show rootBundle, AssetBundle; import 'package:flutter/widgets.dart'; -import 'package:flutter_svg/src/svg_painter.dart'; +import 'src/svg_painter.dart'; class SvgImage extends StatelessWidget { final Size size; @@ -60,11 +60,10 @@ final HttpClient _httpClient = new HttpClient(); Future loadNetworkAsset2(String url) async { final Uri uri = Uri.base.resolve(url); - print('trying $uri'); final HttpClientRequest request = await _httpClient.getUrl(uri); final HttpClientResponse response = await request.close(); - print(response.statusCode); - if (response.statusCode != HttpStatus.OK) throw new FlutterError('Could not get network SVG asset'); + if (response.statusCode != HttpStatus.OK) + throw new HttpException('Could not get network SVG asset', uri: uri); return await consolidateHttpClientResponse(response); } diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index fae2281a1d14..887be0e48793 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -410,3 +410,4 @@ packages: version: "2.1.13" sdks: dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.0d5cf900b021bf5c9fa593ffa12b15bcd1cc5fe0" + flutter: ">=0.3.5 <2.0.0" diff --git a/third_party/test/xml_test.dart b/third_party/test/xml_test.dart new file mode 100644 index 000000000000..dbbd8519b885 --- /dev/null +++ b/third_party/test/xml_test.dart @@ -0,0 +1,23 @@ +import 'package:test/test.dart'; +import 'package:xml/xml.dart'; + +void main() { + // if the parsing logic changes, we can simplify some methods. for now assert that whitespace in attributes is preserved + test('Attribute WhiteSpace test', () { + XmlDocument xd = + parse(''); + + expect( + xd.rootElement.getAttribute('attr'), + ' asdf', + reason: + 'XML Parsing implementation no longer preserves leading whitespace in attributes!', + ); + expect( + xd.rootElement.getAttribute('attr2'), + 'asdf ', + reason: + 'XML Parsing implementation no longer preserves trailing whitespace in attributes!', + ); + }); +} From e0e6b4f33b3c7ba41d5b2183004638ac5de9872a Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 28 Apr 2018 21:15:00 -0400 Subject: [PATCH 022/512] fix for scaling, better gradients, flutter logo close --- third_party/android/.project | 17 ++++++ .../org.eclipse.buildship.core.prefs | 2 + third_party/android/app/.classpath | 6 ++ third_party/android/app/.project | 23 ++++++++ .../org.eclipse.buildship.core.prefs | 2 + third_party/assets/flutter_logo.svg | 25 +------- third_party/lib/http_test.dart | 54 ----------------- third_party/lib/main.dart | 36 +++++------ third_party/lib/src/parsers/parsers.dart | 10 ---- third_party/lib/src/parsers/xml_parsers.dart | 59 ++++++++++++++----- third_party/lib/src/svg_painter.dart | 32 ++++++---- third_party/lib/svg.dart | 21 +++++-- third_party/test/xml_test.dart | 20 +++++++ 13 files changed, 170 insertions(+), 137 deletions(-) create mode 100644 third_party/android/.project create mode 100644 third_party/android/.settings/org.eclipse.buildship.core.prefs create mode 100644 third_party/android/app/.classpath create mode 100644 third_party/android/app/.project create mode 100644 third_party/android/app/.settings/org.eclipse.buildship.core.prefs delete mode 100644 third_party/lib/http_test.dart diff --git a/third_party/android/.project b/third_party/android/.project new file mode 100644 index 000000000000..3964dd3f5b7f --- /dev/null +++ b/third_party/android/.project @@ -0,0 +1,17 @@ + + + android + Project android created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/third_party/android/.settings/org.eclipse.buildship.core.prefs b/third_party/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 000000000000..9ddce8f000ed --- /dev/null +++ b/third_party/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +#Sat Apr 28 20:14:23 EDT 2018 +connection.project.dir= diff --git a/third_party/android/app/.classpath b/third_party/android/app/.classpath new file mode 100644 index 000000000000..8d8d85f14359 --- /dev/null +++ b/third_party/android/app/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/third_party/android/app/.project b/third_party/android/app/.project new file mode 100644 index 000000000000..ac485d7c3e62 --- /dev/null +++ b/third_party/android/app/.project @@ -0,0 +1,23 @@ + + + app + Project app created by Buildship. + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/third_party/android/app/.settings/org.eclipse.buildship.core.prefs b/third_party/android/app/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 000000000000..a7d7283d48ce --- /dev/null +++ b/third_party/android/app/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +#Sat Apr 28 20:14:23 EDT 2018 +connection.project.dir=.. diff --git a/third_party/assets/flutter_logo.svg b/third_party/assets/flutter_logo.svg index 8c19aa227f1c..75c3e365a007 100644 --- a/third_party/assets/flutter_logo.svg +++ b/third_party/assets/flutter_logo.svg @@ -1,26 +1,8 @@ - - - - - - - - - - - - - - - - - - - - - + + + @@ -28,5 +10,4 @@ - \ No newline at end of file diff --git a/third_party/lib/http_test.dart b/third_party/lib/http_test.dart deleted file mode 100644 index 66a9ce257e2c..000000000000 --- a/third_party/lib/http_test.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'dart:convert'; - -const List uriNames = const [ - 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' -]; - -main() async { - uriNames.forEach((uri) async { - String ret = await loadNetworkAsset(uri, null); - print(ret); - }); -} - -Future loadNetworkAsset( - String uri, - Map headers, -) async { - final Uri resolved = Uri.base.resolve(uri); - print('trying $resolved'); - final HttpClientRequest request = await new HttpClient().getUrl(resolved); - headers?.forEach((String name, String value) { - request.headers.add(name, value); - }); - request.headers.removeAll(HttpHeaders.ACCEPT_ENCODING); - final HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.OK) { - throw new Exception( - 'HTTP request failed, statusCode: ${response?.statusCode}, $resolved'); - } - - final String xml = await consolidateHttpClientResponse(response); - if (xml.length == 0) - throw new Exception('NetworkImage is an empty file: $resolved'); - - return xml; -} - -Future consolidateHttpClientResponse(HttpClientResponse response) { - final Completer completer = new Completer.sync(); - final StringBuffer buffer = new StringBuffer(); - - response.transform(UTF8.decoder).listen((String chunk) { - buffer.write(chunk); - //print('CHUNK: $chunk'); - }, onDone: () { - print('DONE'); - completer.complete(buffer.toString()); - }, onError: completer.completeError, cancelOnError: true); - - return completer.future; -} diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 1a7908190b41..8094709e019d 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -5,27 +5,27 @@ const List assetNames = const [ 'assets/flutter_logo.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', - // 'assets/simple/rect_rrect.svg', - // 'assets/w3samples/aa.svg', - // 'assets/w3samples/alphachannel.svg', - // 'assets/deborah_ufw/new-action-expander.svg', - // 'assets/deborah_ufw/new-camera.svg', - // 'assets/deborah_ufw/new-gif-button.svg', - // 'assets/deborah_ufw/new-gif.svg', - // 'assets/deborah_ufw/new-image.svg', - // 'assets/deborah_ufw/new-mention.svg', - // 'assets/deborah_ufw/new-pause-button.svg', - // 'assets/deborah_ufw/new-play-button.svg', - // 'assets/deborah_ufw/new-send-circle.svg', - // 'assets/deborah_ufw/numeric_25.svg', - // 'assets/simple/ellipse.svg', - // 'assets/simple/nested_group.svg', - // 'assets/wikimedia/Ghostscript_Tiger.svg', + 'assets/simple/rect_rrect.svg', + 'assets/w3samples/aa.svg', + 'assets/w3samples/alphachannel.svg', + 'assets/deborah_ufw/new-action-expander.svg', + 'assets/deborah_ufw/new-camera.svg', + 'assets/deborah_ufw/new-gif-button.svg', + 'assets/deborah_ufw/new-gif.svg', + 'assets/deborah_ufw/new-image.svg', + 'assets/deborah_ufw/new-mention.svg', + 'assets/deborah_ufw/new-pause-button.svg', + 'assets/deborah_ufw/new-play-button.svg', + 'assets/deborah_ufw/new-send-circle.svg', + 'assets/deborah_ufw/numeric_25.svg', + 'assets/simple/ellipse.svg', + 'assets/simple/nested_group.svg', + 'assets/wikimedia/Ghostscript_Tiger.svg', ]; const List uriNames = const [ // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' ]; void main() => runApp(new MyApp()); @@ -91,7 +91,7 @@ class _MyHomePageState extends State { max: MediaQuery.of(context).size.width - 10.0, value: _dimension, onChanged: (val) => setState(() => _dimension = val)), - //new FlutterLogo(size: _dimension), + // new FlutterLogo(size: _dimension), new Expanded( child: new GridView.extent( shrinkWrap: true, diff --git a/third_party/lib/src/parsers/parsers.dart b/third_party/lib/src/parsers/parsers.dart index d13875ef8040..947cbfc6602e 100644 --- a/third_party/lib/src/parsers/parsers.dart +++ b/third_party/lib/src/parsers/parsers.dart @@ -3,16 +3,6 @@ import 'dart:math'; import 'package:vector_math/vector_math_64.dart'; -Rect parseViewBox(String viewbox) { - if (viewbox == null || viewbox == '') { - return Rect.zero; - } - - final parts = viewbox.split(' '); - return new Rect.fromLTWH(double.parse(parts[0]), double.parse(parts[1]), - double.parse(parts[2]), double.parse(parts[3])); -} - const String _transformCommandAtom = ' *([^(]+)\\(([^)]*)\\)'; final RegExp _transformValidator = new RegExp('^($_transformCommandAtom)*\$'); final RegExp _transformCommand = new RegExp(_transformCommandAtom); diff --git a/third_party/lib/src/parsers/xml_parsers.dart b/third_party/lib/src/parsers/xml_parsers.dart index 599c9b5020d8..9b5050d0f71d 100644 --- a/third_party/lib/src/parsers/xml_parsers.dart +++ b/third_party/lib/src/parsers/xml_parsers.dart @@ -5,6 +5,35 @@ import 'package:xml/xml.dart'; import '../gradients.dart'; import 'colors.dart'; +Rect parseViewBox(XmlElement svg) { + final String viewBox = _getAttribute(svg, 'viewBox'); + + if (viewBox == '') { + final RegExp notDigits = new RegExp(r'[^\d\.]'); + final String rawWidth = + _getAttribute(svg, 'width').replaceAll(notDigits, ''); + final String rawHeight = + _getAttribute(svg, 'height').replaceAll(notDigits, ''); + if (rawWidth == '' || rawHeight == '') { + return Rect.zero; + } + final double width = double.parse(rawWidth); + final double height = double.parse(rawHeight); + return new Rect.fromLTWH(0.0, 0.0, width, height); + } + + final parts = viewBox.split(new RegExp(r'[ ,]+')); + if (parts.length < 4) { + throw new StateError('viewBox element must be 4 elements long'); + } + return new Rect.fromLTWH( + double.parse(parts[0]), + double.parse(parts[1]), + double.parse(parts[2]), + double.parse(parts[3]), + ); +} + void parseDefs( XmlElement el, Map paintServers, Size size) { el.children.forEach((XmlNode def) { @@ -32,8 +61,6 @@ double _parseDecimalOrPercentage(String val) { } } - - Paint parseLinearGradient(XmlElement el, Size size) { final double x1 = _parseDecimalOrPercentage(_getAttribute(el, 'x1', '0%')); final double x2 = _parseDecimalOrPercentage(_getAttribute(el, 'x2', '100%')); @@ -42,19 +69,17 @@ Paint parseLinearGradient(XmlElement el, Size size) { final Offset from = new Offset(size.width * x1, size.height * y1); final Offset to = new Offset(size.width * x2, size.height * y2); - print('$size $from $to'); final stops = el.findElements('stop').toList(); final Gradient gradient = new Gradient.linear( from, to, stops.map((stop) { - return parseColor(_getAttribute(stop, 'stop-color')).withAlpha( - (double.parse(_getAttribute(stop, 'stop-opacity', '1')).clamp(0, 1) * - 255) - .toInt()); + final String rawOpacity = _getAttribute(stop, 'stop-opacity', '1'); + return parseColor(_getAttribute(stop, 'stop-color')) + .withOpacity(double.parse(rawOpacity)); }).toList(), stops.map((stop) { - String rawOffset = _getAttribute(stop, 'offset'); + final String rawOffset = _getAttribute(stop, 'offset'); return _parseDecimalOrPercentage(rawOffset); }).toList(), ); @@ -65,7 +90,9 @@ Paint parseLinearGradient(XmlElement el, Size size) { Paint parseGradient(XmlElement el, Size size) { if (el.name.local == 'linearGradient') { return parseLinearGradient(el, size); - } else if (el.name.local == 'radialGradient') {} + } else if (el.name.local == 'radialGradient') { + return new Paint()..color = new Color(0xFFABCDEF); + } throw new StateError('Unknown gradient type ${el.name.local}'); } @@ -79,10 +106,10 @@ Paint parseStroke(XmlElement el) { if (rawOpacity == "") { rawOpacity = _getAttribute(el, 'opacity'); } - final opacity = rawOpacity == "" - ? 255 - : (double.parse(rawOpacity).clamp(0.0, 1.0) * 255).toInt(); - final stroke = parseColor(rawStroke).withAlpha(opacity); + final double opacity = rawOpacity == "" + ? 1.0 + : double.parse(rawOpacity).clamp(0.0, 1.0); + final stroke = parseColor(rawStroke).withOpacity(opacity); final rawStrokeCap = _getAttribute(el, 'stroke-linecap'); StrokeCap strokeCap = rawStrokeCap == "null" @@ -141,10 +168,10 @@ Paint parseFill(XmlElement el, Size size, Map paintServers, rawOpacity = _getAttribute(el, 'opacity'); } final opacity = rawOpacity == "" - ? rawFill == 'none' ? 0 : 255 - : (double.parse(rawOpacity).clamp(0.0, 1.0) * 255).toInt(); + ? rawFill == 'none' ? 0.0 : 1.0 + : double.parse(rawOpacity).clamp(0.0, 1.0); - final fill = parseColor(rawFill).withAlpha(opacity); + final fill = parseColor(rawFill).withOpacity(opacity); return new Paint() ..color = fill diff --git a/third_party/lib/src/svg_painter.dart b/third_party/lib/src/svg_painter.dart index 8f9b17c1a265..dead75e23af6 100644 --- a/third_party/lib/src/svg_painter.dart +++ b/third_party/lib/src/svg_painter.dart @@ -1,14 +1,14 @@ +import 'dart:typed_data'; + import 'package:xml/xml.dart'; import 'package:flutter/widgets.dart'; import 'elements.dart'; import 'gradients.dart'; -import 'parsers/parsers.dart'; import 'parsers/xml_parsers.dart'; - class SvgPainter extends CustomPainter { - final _rawSvg; + final XmlDocument _rawSvg; final bool _clipToViewBox; SvgPainter(String rawSvg, {bool clipToViewBox = true}) @@ -19,16 +19,22 @@ class SvgPainter extends CustomPainter { void paint(Canvas canvas, Size size) { if (_rawSvg == null) return; - final String viewBox = _rawSvg.rootElement.getAttribute('viewBox') ?? - '0 0 ' - '${_rawSvg.rootElement.getAttribute('width') ?? '0'} ' - '${_rawSvg.rootElement.getAttribute('height') ?? '0'}'; - - final vbRect = parseViewBox(viewBox); - canvas.scale( - size.width / vbRect.size.width, - size.height / vbRect.size.height, - ); + final Rect vbRect = parseViewBox(_rawSvg.rootElement); + + final double xscale = size.width / vbRect.size.width; + final double yscale = size.height / vbRect.size.height; + + if (xscale == yscale) { + canvas.scale(xscale, yscale); + } else if (xscale < yscale) { + final double xtranslate = (vbRect.size.width - vbRect.size.height) / 2; + canvas.scale(xscale, xscale); + canvas.translate(0.0, xtranslate); + } else { + final double ytranslate = (vbRect.size.height - vbRect.size.width) / 2; + canvas.scale(yscale, yscale); + canvas.translate(ytranslate, 0.0); + } if (_clipToViewBox) { canvas.clipRect(vbRect.translate(vbRect.left, vbRect.top)); diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index fc5d49244150..82a3897357dd 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -15,20 +15,33 @@ class SvgImage extends StatelessWidget { const SvgImage._(this.future, this.size, {this.clipToViewBox = true, Key key}) : super(key: key); - factory SvgImage.asset(String assetName, Size size, - {Key key, AssetBundle bundle, String package}) { + factory SvgImage.asset( + String assetName, + Size size, { + Key key, + AssetBundle bundle, + String package, + bool clipToViewBox = true, + }) { return new SvgImage._( loadAsset(assetName, bundle, package), size, + clipToViewBox: clipToViewBox, key: key, ); } - factory SvgImage.network(String uri, Size size, - {Map headers, Key key}) { + factory SvgImage.network( + String uri, + Size size, { + Map headers, + Key key, + bool clipToViewBox = true, + }) { return new SvgImage._( loadNetworkAsset2(uri), size, + clipToViewBox: clipToViewBox, key: key, ); } diff --git a/third_party/test/xml_test.dart b/third_party/test/xml_test.dart index dbbd8519b885..6c084ac890bf 100644 --- a/third_party/test/xml_test.dart +++ b/third_party/test/xml_test.dart @@ -1,6 +1,10 @@ +import 'dart:ui'; + import 'package:test/test.dart'; import 'package:xml/xml.dart'; +import 'package:flutter_svg/src/parsers/xml_parsers.dart'; + void main() { // if the parsing logic changes, we can simplify some methods. for now assert that whitespace in attributes is preserved test('Attribute WhiteSpace test', () { @@ -20,4 +24,20 @@ void main() { 'XML Parsing implementation no longer preserves trailing whitespace in attributes!', ); }); + + test('viewBox tests', () { + final Rect rect = new Rect.fromLTWH(0.0, 0.0, 100.0, 100.0); + + XmlElement svgWithViewBox = + parse('').rootElement; + XmlElement svgWithViewBoxAndWidthHeight = + parse('') + .rootElement; + XmlElement svgWithWidthHeight = + parse('').rootElement; + + expect(parseViewBox(svgWithViewBox), rect); + expect(parseViewBox(svgWithViewBoxAndWidthHeight), rect); + expect(parseViewBox(svgWithWidthHeight), rect); + }); } From 92c08f370d867f4b651a3b0fee2e6f392a168453 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 29 Apr 2018 08:24:41 -0400 Subject: [PATCH 023/512] allow user to decide foreground or background for painting --- third_party/lib/main.dart | 2 +- third_party/lib/svg.dart | 42 +++++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 8094709e019d..94b352a96a69 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -87,7 +87,7 @@ class _MyHomePageState extends State { ), body: new Column(children: [ new Slider( - min: 1.0, + min: 5.0, max: MediaQuery.of(context).size.width - 10.0, value: _dimension, onChanged: (val) => setState(() => _dimension = val)), diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 82a3897357dd..e74c428c3833 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -7,42 +7,46 @@ import 'package:flutter/widgets.dart'; import 'src/svg_painter.dart'; +enum PaintLocation { Foreground, Background } + class SvgImage extends StatelessWidget { final Size size; final Future future; final bool clipToViewBox; + final PaintLocation paintLocation; - const SvgImage._(this.future, this.size, {this.clipToViewBox = true, Key key}) + const SvgImage._(this.future, this.size, + {this.clipToViewBox = true, + Key key, + this.paintLocation = PaintLocation.Foreground}) : super(key: key); - factory SvgImage.asset( - String assetName, - Size size, { - Key key, - AssetBundle bundle, - String package, - bool clipToViewBox = true, - }) { + factory SvgImage.asset(String assetName, Size size, + {Key key, + AssetBundle bundle, + String package, + bool clipToViewBox = true, + PaintLocation paintLocation = PaintLocation.Foreground}) { return new SvgImage._( loadAsset(assetName, bundle, package), size, clipToViewBox: clipToViewBox, key: key, + paintLocation: paintLocation, ); } - factory SvgImage.network( - String uri, - Size size, { - Map headers, - Key key, - bool clipToViewBox = true, - }) { + factory SvgImage.network(String uri, Size size, + {Map headers, + Key key, + bool clipToViewBox = true, + PaintLocation paintLocation = PaintLocation.Foreground}) { return new SvgImage._( loadNetworkAsset2(uri), size, clipToViewBox: clipToViewBox, key: key, + paintLocation: paintLocation, ); } @@ -51,9 +55,13 @@ class SvgImage extends StatelessWidget { future: future, builder: ((context, snapShot) { if (snapShot.hasData) { + final SvgPainter painter = + new SvgPainter(snapShot.data, clipToViewBox: clipToViewBox); return new CustomPaint( painter: - new SvgPainter(snapShot.data, clipToViewBox: clipToViewBox), + paintLocation == PaintLocation.Background ? painter : null, + foregroundPainter: + paintLocation == PaintLocation.Foreground ? painter : null, size: size); } return new LimitedBox(); From 23e20463b06e147c39178f46a014c7a6cc7aa74e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 29 Apr 2018 11:57:01 -0400 Subject: [PATCH 024/512] default to background --- third_party/lib/svg.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index e74c428c3833..496c57a30d05 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -18,7 +18,7 @@ class SvgImage extends StatelessWidget { const SvgImage._(this.future, this.size, {this.clipToViewBox = true, Key key, - this.paintLocation = PaintLocation.Foreground}) + this.paintLocation = PaintLocation.Background}) : super(key: key); factory SvgImage.asset(String assetName, Size size, @@ -26,7 +26,7 @@ class SvgImage extends StatelessWidget { AssetBundle bundle, String package, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Foreground}) { + PaintLocation paintLocation = PaintLocation.Background}) { return new SvgImage._( loadAsset(assetName, bundle, package), size, @@ -40,7 +40,7 @@ class SvgImage extends StatelessWidget { {Map headers, Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Foreground}) { + PaintLocation paintLocation = PaintLocation.Background}) { return new SvgImage._( loadNetworkAsset2(uri), size, From 3c99255746149d86ff19f376db806272bb8ef72b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 29 Apr 2018 17:57:14 -0400 Subject: [PATCH 025/512] refactor to start decoupling parsing from drawing --- third_party/lib/src/elements.dart | 212 ------------------ third_party/lib/src/gradients.dart | 3 - .../lib/src/{parsers => svg}/colors.dart | 0 .../lib/src/{parsers => svg}/parsers.dart | 0 .../lib/src/{parsers => svg}/xml_parsers.dart | 2 +- third_party/lib/src/svg_painter.dart | 58 ----- third_party/lib/src/svg_parser.dart | 178 +++++++++++++++ third_party/lib/src/vector_painter.dart | 174 ++++++++++++++ third_party/lib/svg.dart | 23 +- third_party/test/xml_test.dart | 2 +- 10 files changed, 372 insertions(+), 280 deletions(-) delete mode 100644 third_party/lib/src/elements.dart delete mode 100644 third_party/lib/src/gradients.dart rename third_party/lib/src/{parsers => svg}/colors.dart (100%) rename third_party/lib/src/{parsers => svg}/parsers.dart (100%) rename third_party/lib/src/{parsers => svg}/xml_parsers.dart (99%) delete mode 100644 third_party/lib/src/svg_painter.dart create mode 100644 third_party/lib/src/svg_parser.dart create mode 100644 third_party/lib/src/vector_painter.dart diff --git a/third_party/lib/src/elements.dart b/third_party/lib/src/elements.dart deleted file mode 100644 index bf932619a286..000000000000 --- a/third_party/lib/src/elements.dart +++ /dev/null @@ -1,212 +0,0 @@ -import 'dart:ui'; - -import 'package:xml/xml.dart'; -import 'package:path_drawing/path_drawing.dart'; -import 'package:vector_math/vector_math_64.dart'; - -import 'gradients.dart'; -import 'parsers/parsers.dart'; -import 'parsers/xml_parsers.dart'; - -typedef SvgShapeInfo SvgPathFactory(XmlElement el); -final Map _shapes = { - 'circle': (el) => new SvgShapeInfo.fromSvgCircle(el), - 'path': (el) => new SvgShapeInfo.fromSvgPath(el), - 'rect': (el) => new SvgShapeInfo.fromSvgRect(el), - 'polygon': (el) => new SvgShapeInfo.fromSvgPolygonOrLine(el), - 'polyline': (el) => new SvgShapeInfo.fromSvgPolygonOrLine(el), - 'ellipse': (el) => new SvgShapeInfo.fromSvgEllipse(el), - 'line': (el) => new SvgShapeInfo.fromSvgLine(el), -}; - -class SvgShapeInfo { - const SvgShapeInfo(this.path, this.size); - final Path path; - final Size size; - - static Path transformPath(Path path, XmlElement el) { - assert(path != null); - assert(el != null); - - final transform = parseTransform(el.getAttribute('transform')); - - if (transform != null) { - return path.transform(transform.storage); - } else { - return path; - } - } - - factory SvgShapeInfo.fromSvgCircle(XmlElement el) { - final cx = double.parse(el.getAttribute('cx')); - final cy = double.parse(el.getAttribute('cy')); - final r = double.parse(el.getAttribute('r')); - final oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); - final path = new Path()..addOval(oval); - return new SvgShapeInfo(transformPath(path, el), oval.size); - } - - factory SvgShapeInfo.fromSvgPath(XmlElement el) { - final d = el.getAttribute('d'); - final Path p = parseSvgPathData(d); - return new SvgShapeInfo(transformPath(p, el), p.getBounds().size); - } - - factory SvgShapeInfo.fromSvgRect(XmlElement el) { - final double x = double.parse(el.getAttribute('x')); - final double y = double.parse(el.getAttribute('y')); - final double w = double.parse(el.getAttribute('width')); - final double h = double.parse(el.getAttribute('height')); - final Rect rect = new Rect.fromLTWH(x, y, w, h); - String rxRaw = el.getAttribute('rx'); - String ryRaw = el.getAttribute('ry'); - rxRaw ??= ryRaw; - ryRaw ??= rxRaw; - - if ((rxRaw != null && rxRaw != "")) { - final double rx = double.parse(rxRaw); - final double ry = double.parse(ryRaw); - return new SvgShapeInfo( - transformPath( - new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)), el), - rect.size, - ); - } - - final path = new Path()..addRect(rect); - return new SvgShapeInfo(transformPath(path, el), rect.size); - } - - factory SvgShapeInfo.fromSvgPolygonOrLine(XmlElement el) { - final path = parseSvgPathData('M' + el.getAttribute('points') + 'z'); - - return SvgShapeInfo(transformPath(path, el), path.getBounds().size); - } - - factory SvgShapeInfo.fromSvgEllipse(XmlElement el) { - final cx = double.parse(el.getAttribute('cx')); - final cy = double.parse(el.getAttribute('cy')); - final rx = double.parse(el.getAttribute('rx')); - final ry = double.parse(el.getAttribute('ry')); - - Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); - - return new SvgShapeInfo(transformPath(new Path()..addOval(r), el), r.size); - } - - factory SvgShapeInfo.fromSvgLine(XmlElement el) { - final x1 = double.parse(el.getAttribute('x1')); - final x2 = double.parse(el.getAttribute('x2')); - final y1 = double.parse(el.getAttribute('y1')); - final y2 = double.parse(el.getAttribute('y2')); - - final path = new Path() - ..moveTo(x1, x2) - ..lineTo(y1, y2); - return new SvgShapeInfo(transformPath(path, el), path.getBounds().size); - } -} - -class SvgElement { - final String name; - const SvgElement(this.name); - void draw(Canvas canvas, [Paint parentPaint]) {} - - factory SvgElement.fromXml( - XmlElement el, Map paintServers, Size size) { - if (el.name.local == 'defs') { - parseDefs(el, paintServers, size); - } else if (el.name.local == 'g') { - return new SvgGroup.fromXml(el, paintServers, size); - } else if (_shapes.containsKey(el.name.local)) { - return new SvgShape.fromXml(el, paintServers, size); - } - return new SvgElement(el.name.local); - } -} - -class SvgShape extends SvgElement { - final Path path; - final Paint stroke; - final Paint fill; - - const SvgShape(this.path, this.stroke, this.fill, String elementName) - : assert(path != null, '$elementName had a null path'), - super(elementName); - - @override - void draw(Canvas canvas, [Paint parentPaint]) { - if (parentPaint != null) { - canvas.drawPath(path, parentPaint); - return; - } - if (stroke != null) canvas.drawPath(path, stroke); - if (fill != null) canvas.drawPath(path, fill); - } - - factory SvgShape.fromXml( - XmlElement el, Map paintServers, Size size) { - final ret = _shapes[el.name.local](el); - final stroke = parseStroke(el); - final fill = parseFill(el, ret.size, paintServers); - - return new SvgShape(ret.path, stroke, fill, el.name.local); - } -} - -class SvgGroup extends SvgElement { - final List children; - final Paint stroke; - final Paint fill; - final Matrix4 transform; - const SvgGroup(this.children, this.transform, this.stroke, this.fill) - : super('g'); - - factory SvgGroup.fromXml( - XmlElement el, Map paintServers, Size size) { - var children = new List(); - el.children.forEach((child) { - if (child is XmlElement) { - final SvgElement el = new SvgElement.fromXml(child, paintServers, size); - if (el != null) { - children.add(el); - } - } - }); - - final transform = parseTransform(el.getAttribute('transform')); - final fill = parseFill(el, size, paintServers, isShape: false); - final stroke = parseStroke(el); - - return new SvgGroup( - children, - //TODO: when Dart2 is around use this instead of above - // el.children - // .whereType() - // .map((child) => new SvgBaseElement.fromXml(child)), - transform, stroke, fill, - ); - } - - @override - void draw(Canvas canvas, [Paint parentPaint]) { - if (transform != null) { - canvas.save(); - canvas.transform(transform.storage); - } - children.forEach((child) { - if (stroke != null) { - child.draw(canvas, stroke); - } - if (fill != null) { - child.draw(canvas, fill); - } - if (stroke == null && fill == null) { - child.draw(canvas); - } - }); - if (transform != null) { - canvas.restore(); - } - } -} diff --git a/third_party/lib/src/gradients.dart b/third_party/lib/src/gradients.dart deleted file mode 100644 index e65f21269ce6..000000000000 --- a/third_party/lib/src/gradients.dart +++ /dev/null @@ -1,3 +0,0 @@ -import 'dart:ui'; - -typedef Paint PaintServer(Size size); \ No newline at end of file diff --git a/third_party/lib/src/parsers/colors.dart b/third_party/lib/src/svg/colors.dart similarity index 100% rename from third_party/lib/src/parsers/colors.dart rename to third_party/lib/src/svg/colors.dart diff --git a/third_party/lib/src/parsers/parsers.dart b/third_party/lib/src/svg/parsers.dart similarity index 100% rename from third_party/lib/src/parsers/parsers.dart rename to third_party/lib/src/svg/parsers.dart diff --git a/third_party/lib/src/parsers/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart similarity index 99% rename from third_party/lib/src/parsers/xml_parsers.dart rename to third_party/lib/src/svg/xml_parsers.dart index 9b5050d0f71d..90a0525cb8f4 100644 --- a/third_party/lib/src/parsers/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -2,7 +2,7 @@ import 'dart:ui'; import 'package:xml/xml.dart'; -import '../gradients.dart'; +import '../vector_painter.dart'; import 'colors.dart'; Rect parseViewBox(XmlElement svg) { diff --git a/third_party/lib/src/svg_painter.dart b/third_party/lib/src/svg_painter.dart deleted file mode 100644 index dead75e23af6..000000000000 --- a/third_party/lib/src/svg_painter.dart +++ /dev/null @@ -1,58 +0,0 @@ -import 'dart:typed_data'; - -import 'package:xml/xml.dart'; -import 'package:flutter/widgets.dart'; - -import 'elements.dart'; -import 'gradients.dart'; -import 'parsers/xml_parsers.dart'; - -class SvgPainter extends CustomPainter { - final XmlDocument _rawSvg; - final bool _clipToViewBox; - - SvgPainter(String rawSvg, {bool clipToViewBox = true}) - : _rawSvg = parse(rawSvg), - _clipToViewBox = clipToViewBox; - - @override - void paint(Canvas canvas, Size size) { - if (_rawSvg == null) return; - - final Rect vbRect = parseViewBox(_rawSvg.rootElement); - - final double xscale = size.width / vbRect.size.width; - final double yscale = size.height / vbRect.size.height; - - if (xscale == yscale) { - canvas.scale(xscale, yscale); - } else if (xscale < yscale) { - final double xtranslate = (vbRect.size.width - vbRect.size.height) / 2; - canvas.scale(xscale, xscale); - canvas.translate(0.0, xtranslate); - } else { - final double ytranslate = (vbRect.size.height - vbRect.size.width) / 2; - canvas.scale(yscale, yscale); - canvas.translate(ytranslate, 0.0); - } - - if (_clipToViewBox) { - canvas.clipRect(vbRect.translate(vbRect.left, vbRect.top)); - } - final Map paintServers = {}; - - for (var el in _rawSvg.rootElement.children) { - if (el is XmlElement) { - if (el.name.local == 'defs') { - parseDefs(el, paintServers, size); - } else { - new SvgElement.fromXml(el, paintServers, size).draw(canvas); - } - } - } - } - - @override - bool shouldRepaint(SvgPainter oldPainter) => - _rawSvg != null && oldPainter._rawSvg != _rawSvg; -} diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart new file mode 100644 index 000000000000..6e87d60448b1 --- /dev/null +++ b/third_party/lib/src/svg_parser.dart @@ -0,0 +1,178 @@ +import 'dart:ui'; + +import 'package:xml/xml.dart'; +import 'package:path_drawing/path_drawing.dart'; +import 'package:vector_math/vector_math_64.dart'; + +import 'vector_painter.dart'; +import 'svg/parsers.dart'; +import 'svg/xml_parsers.dart'; + +typedef DrawableSvgShape SvgShapeFactory( + XmlElement el, Map paintServers); + +final Map _shapes = { + 'circle': (XmlElement el, Map paintServers) => + new DrawableSvgShape.fromSvgCircle(el, paintServers), + 'path': (XmlElement el, Map paintServers) => + new DrawableSvgShape.fromSvgPath(el, paintServers), + 'rect': (XmlElement el, Map paintServers) => + new DrawableSvgShape.fromSvgRect(el, paintServers), + 'polygon': (XmlElement el, Map paintServers) => + new DrawableSvgShape.fromSvgPolygonOrLine(el, paintServers), + 'polyline': (XmlElement el, Map paintServers) => + new DrawableSvgShape.fromSvgPolygonOrLine(el, paintServers), + 'ellipse': (XmlElement el, Map paintServers) => + new DrawableSvgShape.fromSvgEllipse(el, paintServers), + 'line': (XmlElement el, Map paintServers) => + new DrawableSvgShape.fromSvgLine(el, paintServers), +}; + +class DrawableSvgShape extends DrawableShape { + const DrawableSvgShape(Path path, Size size, {Paint stroke, Paint fill}) + : super(path, size, stroke: stroke, fill: fill); + + static Path transformPath(Path path, XmlElement el) { + assert(path != null); + assert(el != null); + + final Matrix4 transform = parseTransform(el.getAttribute('transform')); + + if (transform != null) { + return path.transform(transform.storage); + } else { + return path; + } + } + + static _createDrawable(Path path, Size size, + Map paintServers, XmlElement el) { + final stroke = parseStroke(el); + final fill = parseFill(el, size, paintServers); + + return new DrawableSvgShape(transformPath(path, el), size, + stroke: stroke, fill: fill); + } + + factory DrawableSvgShape.fromSvgCircle( + XmlElement el, Map paintServers) { + final cx = double.parse(el.getAttribute('cx')); + final cy = double.parse(el.getAttribute('cy')); + final r = double.parse(el.getAttribute('r')); + final oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); + final path = new Path()..addOval(oval); + + return _createDrawable(path, oval.size, paintServers, el); + } + + factory DrawableSvgShape.fromSvgPath( + XmlElement el, Map paintServers) { + final d = el.getAttribute('d'); + final Path path = parseSvgPathData(d); + return _createDrawable(path, path.getBounds().size, paintServers, el); + } + + factory DrawableSvgShape.fromSvgRect( + XmlElement el, Map paintServers) { + final double x = double.parse(el.getAttribute('x')); + final double y = double.parse(el.getAttribute('y')); + final double w = double.parse(el.getAttribute('width')); + final double h = double.parse(el.getAttribute('height')); + final Rect rect = new Rect.fromLTWH(x, y, w, h); + String rxRaw = el.getAttribute('rx'); + String ryRaw = el.getAttribute('ry'); + rxRaw ??= ryRaw; + ryRaw ??= rxRaw; + + if ((rxRaw != null && rxRaw != "")) { + final double rx = double.parse(rxRaw); + final double ry = double.parse(ryRaw); + + return _createDrawable( + new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)), + rect.size, + paintServers, + el, + ); + } + + final path = new Path()..addRect(rect); + return _createDrawable(path, rect.size, paintServers, el); + } + + factory DrawableSvgShape.fromSvgPolygonOrLine( + XmlElement el, Map paintServers) { + final path = parseSvgPathData('M' + el.getAttribute('points') + 'z'); + + return _createDrawable(path, path.getBounds().size, paintServers, el); + } + + factory DrawableSvgShape.fromSvgEllipse( + XmlElement el, Map paintServers) { + final cx = double.parse(el.getAttribute('cx')); + final cy = double.parse(el.getAttribute('cy')); + final rx = double.parse(el.getAttribute('rx')); + final ry = double.parse(el.getAttribute('ry')); + + Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); + + return _createDrawable(new Path()..addOval(r), r.size, paintServers, el); + } + + factory DrawableSvgShape.fromSvgLine( + XmlElement el, Map paintServers) { + final x1 = double.parse(el.getAttribute('x1')); + final x2 = double.parse(el.getAttribute('x2')); + final y1 = double.parse(el.getAttribute('y1')); + final y2 = double.parse(el.getAttribute('y2')); + + final path = new Path() + ..moveTo(x1, x2) + ..lineTo(y1, y2); + return _createDrawable(path, path.getBounds().size, paintServers, el); + } +} + +Drawable parseSvgElement( + XmlElement el, Map paintServers, Size size) { + final SvgShapeFactory shapeFn = _shapes[el.name.local]; + if (shapeFn != null) { + return shapeFn(el, paintServers); + } else if (el.name.local == 'defs') { + parseDefs(el, paintServers, size); + } else if (el.name.local == 'g') { + return parseSvgGroup(el, paintServers, size); + } + if (el.name.local == 'svg') { + throw new UnsupportedError( + 'Nested SVGs not supported in this implementation.'); + } + print('Unhandled element ${el.name.local}'); + return new DrawableNoop(el.name.local); +} + +Drawable parseSvgGroup( + XmlElement el, Map paintServers, Size size) { + final List children = []; + el.children.forEach((child) { + if (child is XmlElement) { + final Drawable el = parseSvgElement(child, paintServers, size); + if (el != null) { + children.add(el); + } + } + }); + + final Matrix4 transform = parseTransform(el.getAttribute('transform')); + final Paint fill = parseFill(el, size, paintServers, isShape: false); + final Paint stroke = parseStroke(el); + + return new DrawableGroup( + children, + //TODO: when Dart2 is around use this instead of above + // el.children + // .whereType() + // .map((child) => new SvgBaseElement.fromXml(child)), + transform?.storage, stroke, fill, + ); +} diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart new file mode 100644 index 000000000000..cba21f5ed3a0 --- /dev/null +++ b/third_party/lib/src/vector_painter.dart @@ -0,0 +1,174 @@ +import 'dart:typed_data'; + +import 'package:flutter/widgets.dart'; +import 'package:meta/meta.dart'; + +typedef Paint PaintServer(Size size); + +/// Base interface for vector drawing. +@immutable +abstract class Drawable { + /// Whether this [Drawable] would be visible if [draw]n. + bool get isVisible; + + /// Draws the contents or children of this [Drawable] to the `canvas`, using + /// the `parentPaint` to optionally override the child's paint. + void draw(Canvas canvas, [Paint parentPaint]); +} + +/// The root element of a drawable. +class DrawableRoot implements Drawable { + /// The expected coordinates used by child paths for drawing. + final Rect viewBox; + + /// The actual child or group to draw. + final List children; + + const DrawableRoot(this.viewBox, this.children); + + /// Scales the `canvas` so that the drawing units in this [Drawable] + /// will scale to the `desiredSize`. + /// + /// If the `viewBox` dimensions are not 1:1 with `desiredSize`, will scale to + /// the smaller dimension and translate to center the image along the larger + /// dimension. + void scaleToViewBox(Canvas canvas, Size desiredSize) { + final double xscale = desiredSize.width / viewBox.size.width; + final double yscale = desiredSize.height / viewBox.size.height; + + if (xscale == yscale) { + canvas.scale(xscale, yscale); + } else if (xscale < yscale) { + final double xtranslate = (viewBox.size.width - viewBox.size.height) / 2; + canvas.scale(xscale, xscale); + canvas.translate(0.0, xtranslate); + } else { + final double ytranslate = (viewBox.size.height - viewBox.size.width) / 2; + canvas.scale(yscale, yscale); + canvas.translate(ytranslate, 0.0); + } + } + + /// Clips the canvas to a rect corresponding to the `viewBox`. + void clipToViewBox(Canvas canvas) { + canvas.clipRect(viewBox.translate(viewBox.left, viewBox.top)); + } + + @override + bool get isVisible => + children.isNotEmpty == true && viewBox != null && !viewBox.isEmpty; + + @override + void draw(Canvas canvas, [Paint parentPaint]) { + children.forEach((child) => child.draw(canvas, parentPaint)); + } +} + +class DrawableNoop implements Drawable { + final String name; + const DrawableNoop(this.name); + + @override + bool get isVisible => false; + + @override + void draw(Canvas canvas, [Paint parentPaint]) { + print('Attempted to draw $name'); + } +} + +class DrawableGroup implements Drawable { + final List children; + final Paint stroke; + final Paint fill; + final Float64List transform; + + const DrawableGroup(this.children, this.transform, this.stroke, this.fill); + + @override + bool get isVisible => children != null && children.length > 0; + + @override + void draw(Canvas canvas, [Paint parentPaint]) { + if (transform != null) { + canvas.save(); + canvas.transform(transform); + } + children.forEach((child) { + if (stroke != null) { + child.draw(canvas, stroke); + } + if (fill != null) { + child.draw(canvas, fill); + } + if (stroke == null && fill == null) { + child.draw(canvas); + } + }); + if (transform != null) { + canvas.restore(); + } + } +} + +class DrawableShape implements Drawable { + final Paint stroke; + final Paint fill; + final Path path; + final Size size; + + const DrawableShape(this.path, this.size, {this.stroke, this.fill}) + : assert(path != null), + assert(size != null); + + @override + bool get isVisible => !size.isEmpty && (stroke != null || fill != null); + + @override + void draw(Canvas canvas, [Paint parentPaint]) { + if (parentPaint != null) { + canvas.drawPath(path, parentPaint); + return; + } + if (stroke != null) canvas.drawPath(path, stroke); + if (fill != null) canvas.drawPath(path, fill); + } +} + +class VectorPainter extends CustomPainter { + final DrawableRoot drawable; + final Map paintServers; + final bool _clipToViewBox; + + VectorPainter(this.drawable, this.paintServers, {bool clipToViewBox = true}) + : _clipToViewBox = clipToViewBox; + + @override + void paint(Canvas canvas, Size size) { + if (drawable == null || + drawable.viewBox == null || + drawable.viewBox.size.width == 0) return; + + drawable.scaleToViewBox(canvas, size); + if (_clipToViewBox) { + drawable.clipToViewBox(canvas); + } + + drawable.draw(canvas); + // final Map paintServers = {}; + // + // for (var el in _rawSvg.rootElement.children) { + // if (el is XmlElement) { + // if (el.name.local == 'defs') { + // parseDefs(el, paintServers, size); + // } else { + // new SvgElement.fromXml(el, paintServers, size).draw(canvas); + // } + // } + // } + } + + @override + bool shouldRepaint(VectorPainter oldPainter) => true; + // _rawSvg != null && oldPainter._rawSvg != _rawSvg; +} diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 496c57a30d05..f90228f6de7b 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -4,8 +4,11 @@ import 'dart:convert'; import 'package:flutter/services.dart' show rootBundle, AssetBundle; import 'package:flutter/widgets.dart'; +import 'package:xml/xml.dart' as xml; -import 'src/svg_painter.dart'; +import 'src/vector_painter.dart'; +import 'src/svg_parser.dart'; +import 'src/svg/xml_parsers.dart'; enum PaintLocation { Foreground, Background } @@ -55,8 +58,17 @@ class SvgImage extends StatelessWidget { future: future, builder: ((context, snapShot) { if (snapShot.hasData) { - final SvgPainter painter = - new SvgPainter(snapShot.data, clipToViewBox: clipToViewBox); + final xml.XmlElement svg = xml.parse(snapShot.data).rootElement; + final Rect viewBox = parseViewBox(svg); + Map paintServers = {}; + final List children = svg.children + .where((xml.XmlNode child) => child is xml.XmlElement) + .map((xml.XmlNode child) => + parseSvgElement(child, paintServers, size)) + .toList(); + final DrawableRoot root = new DrawableRoot(viewBox, children); + final CustomPainter painter = new VectorPainter(root, paintServers, + clipToViewBox: clipToViewBox); return new CustomPaint( painter: paintLocation == PaintLocation.Background ? painter : null, @@ -73,8 +85,9 @@ class SvgImage extends StatelessWidget { Future loadAsset(String assetName, [AssetBundle bundle, String package]) async { bundle ??= rootBundle; - return await bundle - .loadString(package == null ? assetName : 'packages/$package/$assetName'); + return await bundle.loadString( + package == null ? assetName : 'packages/$package/$assetName', + cache: false); } final HttpClient _httpClient = new HttpClient(); diff --git a/third_party/test/xml_test.dart b/third_party/test/xml_test.dart index 6c084ac890bf..e6dae2e83994 100644 --- a/third_party/test/xml_test.dart +++ b/third_party/test/xml_test.dart @@ -3,7 +3,7 @@ import 'dart:ui'; import 'package:test/test.dart'; import 'package:xml/xml.dart'; -import 'package:flutter_svg/src/parsers/xml_parsers.dart'; +import 'package:flutter_svg/src/svg/xml_parsers.dart'; void main() { // if the parsing logic changes, we can simplify some methods. for now assert that whitespace in attributes is preserved From 673ac964d6da6ec04e108e2f42a972e588e2fb90 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 29 Apr 2018 19:47:03 -0400 Subject: [PATCH 026/512] Further separation, use RepaintBoundary --- third_party/lib/src/vector_painter.dart | 20 ++--- third_party/lib/svg.dart | 112 +++++++++++++++--------- 2 files changed, 78 insertions(+), 54 deletions(-) diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index cba21f5ed3a0..a3f11c635180 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -24,7 +24,9 @@ class DrawableRoot implements Drawable { /// The actual child or group to draw. final List children; - const DrawableRoot(this.viewBox, this.children); + final Map paintServers; + + const DrawableRoot(this.viewBox, this.children, this.paintServers); /// Scales the `canvas` so that the drawing units in this [Drawable] /// will scale to the `desiredSize`. @@ -137,14 +139,15 @@ class DrawableShape implements Drawable { class VectorPainter extends CustomPainter { final DrawableRoot drawable; - final Map paintServers; final bool _clipToViewBox; - VectorPainter(this.drawable, this.paintServers, {bool clipToViewBox = true}) + VectorPainter(this.drawable, {bool clipToViewBox = true}) : _clipToViewBox = clipToViewBox; @override void paint(Canvas canvas, Size size) { + Rect p; + p.hashCode; if (drawable == null || drawable.viewBox == null || drawable.viewBox.size.width == 0) return; @@ -155,17 +158,6 @@ class VectorPainter extends CustomPainter { } drawable.draw(canvas); - // final Map paintServers = {}; - // - // for (var el in _rawSvg.rootElement.children) { - // if (el is XmlElement) { - // if (el.name.local == 'defs') { - // parseDefs(el, paintServers, size); - // } else { - // new SvgElement.fromXml(el, paintServers, size).draw(canvas); - // } - // } - // } } @override diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index f90228f6de7b..81a98e1e83c3 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -4,7 +4,8 @@ import 'dart:convert'; import 'package:flutter/services.dart' show rootBundle, AssetBundle; import 'package:flutter/widgets.dart'; -import 'package:xml/xml.dart' as xml; +import 'package:xml/xml.dart' hide parse; +import 'package:xml/xml.dart' as xml show parse; import 'src/vector_painter.dart'; import 'src/svg_parser.dart'; @@ -12,18 +13,64 @@ import 'src/svg/xml_parsers.dart'; enum PaintLocation { Foreground, Background } -class SvgImage extends StatelessWidget { +class VectorDrawableImage extends StatelessWidget { final Size size; - final Future future; + final Future future; final bool clipToViewBox; final PaintLocation paintLocation; - const SvgImage._(this.future, this.size, + const VectorDrawableImage._(this.future, this.size, {this.clipToViewBox = true, Key key, this.paintLocation = PaintLocation.Background}) : super(key: key); + Widget build(BuildContext context) { + return new FutureBuilder( + future: future, + builder: ((context, snapShot) { + if (snapShot.hasData) { + final CustomPainter painter = + new VectorPainter(snapShot.data, clipToViewBox: clipToViewBox); + return new RepaintBoundary.wrap( + CustomPaint( + painter: + paintLocation == PaintLocation.Background ? painter : null, + foregroundPainter: + paintLocation == PaintLocation.Foreground ? painter : null, + size: size, + isComplex: true, + willChange: false, + ), + 0); + } + return new LimitedBox(); + }), + ); + } +} + +class SvgImage extends VectorDrawableImage { + SvgImage._(Future future, Size size, + {bool clipToViewBox, Key key, PaintLocation paintLocation}) + : super._(future, size, + clipToViewBox: clipToViewBox, + key: key, + paintLocation: paintLocation); + + factory SvgImage.fromString(String svg, Size size, + {Key key, + bool clipToViewBox = true, + PaintLocation paintLocation = PaintLocation.Background}) { + return new SvgImage._( + new Future.value(fromSvgString(svg, size)), + size, + clipToViewBox: clipToViewBox, + key: key, + paintLocation: paintLocation, + ); + } + factory SvgImage.asset(String assetName, Size size, {Key key, AssetBundle bundle, @@ -31,7 +78,7 @@ class SvgImage extends StatelessWidget { bool clipToViewBox = true, PaintLocation paintLocation = PaintLocation.Background}) { return new SvgImage._( - loadAsset(assetName, bundle, package), + loadAsset(assetName, size, bundle: bundle, package: package), size, clipToViewBox: clipToViewBox, key: key, @@ -45,60 +92,45 @@ class SvgImage extends StatelessWidget { bool clipToViewBox = true, PaintLocation paintLocation = PaintLocation.Background}) { return new SvgImage._( - loadNetworkAsset2(uri), + loadNetworkAsset2(uri, size), size, clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, ); } +} - Widget build(BuildContext context) { - return new FutureBuilder( - future: future, - builder: ((context, snapShot) { - if (snapShot.hasData) { - final xml.XmlElement svg = xml.parse(snapShot.data).rootElement; - final Rect viewBox = parseViewBox(svg); - Map paintServers = {}; - final List children = svg.children - .where((xml.XmlNode child) => child is xml.XmlElement) - .map((xml.XmlNode child) => - parseSvgElement(child, paintServers, size)) - .toList(); - final DrawableRoot root = new DrawableRoot(viewBox, children); - final CustomPainter painter = new VectorPainter(root, paintServers, - clipToViewBox: clipToViewBox); - return new CustomPaint( - painter: - paintLocation == PaintLocation.Background ? painter : null, - foregroundPainter: - paintLocation == PaintLocation.Foreground ? painter : null, - size: size); - } - return new LimitedBox(); - }), - ); - } +DrawableRoot fromSvgString(String rawSvg, Size size) { + final XmlElement svg = xml.parse(rawSvg).rootElement; + final Rect viewBox = parseViewBox(svg); + Map paintServers = {}; + final List children = svg.children + .where((XmlNode child) => child is XmlElement) + .map((XmlNode child) => parseSvgElement(child, paintServers, size)) + .toList(); + return new DrawableRoot(viewBox, children, {}); } -Future loadAsset(String assetName, - [AssetBundle bundle, String package]) async { +Future loadAsset(String assetName, Size size, + {AssetBundle bundle, String package}) async { bundle ??= rootBundle; - return await bundle.loadString( - package == null ? assetName : 'packages/$package/$assetName', - cache: false); + final String rawSvg = await bundle.loadString( + package == null ? assetName : 'packages/$package/$assetName', + ); + return fromSvgString(rawSvg, size); } final HttpClient _httpClient = new HttpClient(); -Future loadNetworkAsset2(String url) async { +Future loadNetworkAsset2(String url, Size size) async { final Uri uri = Uri.base.resolve(url); final HttpClientRequest request = await _httpClient.getUrl(uri); final HttpClientResponse response = await request.close(); if (response.statusCode != HttpStatus.OK) throw new HttpException('Could not get network SVG asset', uri: uri); - return await consolidateHttpClientResponse(response); + final String rawSvg = await consolidateHttpClientResponse(response); + return fromSvgString(rawSvg, size); } Future consolidateHttpClientResponse( From 65a2347ee218d8af4d90052d6d91b9b148c8c146 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 29 Apr 2018 20:29:06 -0400 Subject: [PATCH 027/512] Minor refactoring, document more methods/classes --- third_party/lib/src/svg/colors.dart | 3 +- third_party/lib/src/svg/parsers.dart | 4 ++ third_party/lib/src/svg/xml_parsers.dart | 67 +++++++++++++----------- third_party/lib/src/svg_parser.dart | 18 +++++-- third_party/lib/src/vector_painter.dart | 5 +- third_party/lib/svg.dart | 13 +++-- 6 files changed, 70 insertions(+), 40 deletions(-) diff --git a/third_party/lib/src/svg/colors.dart b/third_party/lib/src/svg/colors.dart index 64c4cd868d55..d2c01e3a2a46 100644 --- a/third_party/lib/src/svg/colors.dart +++ b/third_party/lib/src/svg/colors.dart @@ -2,6 +2,7 @@ import 'dart:ui'; const colorBlack = const Color.fromARGB(255, 0, 0, 0); +/// Converts a SVG Color String (either a # prefixed color string or a named color) to a [Color]. Color parseColor(String colorString) { if (colorString == null || colorString.length == 0) { return const Color.fromARGB(255, 0, 0, 0); @@ -31,7 +32,7 @@ Color parseColor(String colorString) { } throw new ArgumentError.value( - colorString, "colorString", "Unknown color $colorString"); + colorString, 'colorString', 'Unknown color $colorString'); } // https://www.w3.org/TR/SVG11/types.html#ColorKeywords diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index 947cbfc6602e..662a6cda3949 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -18,6 +18,10 @@ const Map _matrixParsers = const { 'skewY': _parseSvgSkewY, }; +/// Parses a SVG transform attribute into a [Matrix4]. +/// +/// Based on work in the "vi-tool" by @amirh, but extended to support additional +/// transforms and use a Matrix4 rather than Matrix3 for the affine matrices. Matrix4 parseTransform(String transform) { if (transform == null) { return null; diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 90a0525cb8f4..e8c69506393a 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -5,6 +5,7 @@ import 'package:xml/xml.dart'; import '../vector_painter.dart'; import 'colors.dart'; +/// Parses an SVG @viewBox attribute (e.g. 0 0 100 100) to a [Rect]. Rect parseViewBox(XmlElement svg) { final String viewBox = _getAttribute(svg, 'viewBox'); @@ -34,6 +35,7 @@ Rect parseViewBox(XmlElement svg) { ); } +/// Parses a element, extracting and (TODO) elements into the `paintServers` map. void parseDefs( XmlElement el, Map paintServers, Size size) { el.children.forEach((XmlNode def) { @@ -47,10 +49,10 @@ void parseDefs( } /// Gets the attribute, trims it, and returns the attribute or default if the attribute -/// is null or "" -String _getAttribute(XmlElement el, String name, [String def = ""]) { +/// is null or ''. +String _getAttribute(XmlElement el, String name, [String def = '']) { final String raw = el.getAttribute(name)?.trim(); - return raw == "" || raw == null ? def : raw; + return raw == '' || raw == null ? def : raw; } double _parseDecimalOrPercentage(String val) { @@ -61,6 +63,7 @@ double _parseDecimalOrPercentage(String val) { } } +/// Parses an SVG element into a [Paint]. Paint parseLinearGradient(XmlElement el, Size size) { final double x1 = _parseDecimalOrPercentage(_getAttribute(el, 'x1', '0%')); final double x2 = _parseDecimalOrPercentage(_getAttribute(el, 'x2', '100%')); @@ -87,6 +90,7 @@ Paint parseLinearGradient(XmlElement el, Size size) { return new Paint()..shader = gradient; } +/// Parses a or into a [Paint]. Paint parseGradient(XmlElement el, Size size) { if (el.name.local == 'linearGradient') { return parseLinearGradient(el, size); @@ -96,60 +100,61 @@ Paint parseGradient(XmlElement el, Size size) { throw new StateError('Unknown gradient type ${el.name.local}'); } -Paint parseStroke(XmlElement el) { +/// Parses a @stroke attribute into a [Paint]. +Paint parseStroke( + XmlElement el, Size size, Map paintServers) { final rawStroke = _getAttribute(el, 'stroke'); - if (rawStroke == "") { + if (rawStroke == '') { return null; } + if (rawStroke.startsWith('url')) { + return paintServers[rawStroke](size); + } var rawOpacity = _getAttribute(el, 'stroke-opacity'); - if (rawOpacity == "") { + if (rawOpacity == '') { rawOpacity = _getAttribute(el, 'opacity'); } - final double opacity = rawOpacity == "" - ? 1.0 - : double.parse(rawOpacity).clamp(0.0, 1.0); - final stroke = parseColor(rawStroke).withOpacity(opacity); - - final rawStrokeCap = _getAttribute(el, 'stroke-linecap'); - StrokeCap strokeCap = rawStrokeCap == "null" + final double opacity = + rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); + final Paint paint = new Paint() + ..color = parseColor(rawStroke).withOpacity(opacity) + ..style = PaintingStyle.stroke; + + final String rawStrokeCap = _getAttribute(el, 'stroke-linecap'); + paint.strokeCap = rawStrokeCap == 'null' ? StrokeCap.butt : StrokeCap.values.firstWhere( (sc) => sc.toString() == 'StrokeCap.$rawStrokeCap', orElse: () => StrokeCap.butt); - final rawLineJoin = _getAttribute(el, 'stroke-linejoin'); - StrokeJoin strokeJoin = rawLineJoin == "" + final String rawLineJoin = _getAttribute(el, 'stroke-linejoin'); + paint.strokeJoin = rawLineJoin == '' ? StrokeJoin.miter : StrokeJoin.values.firstWhere( (sj) => sj.toString() == 'StrokeJoin.$rawLineJoin', orElse: () => StrokeJoin.miter); - final rawMiterLimit = _getAttribute(el, 'stroke-miterlimit'); - final miterLimit = rawMiterLimit == "" ? 4.0 : double.parse(rawMiterLimit); + final String rawMiterLimit = _getAttribute(el, 'stroke-miterlimit'); + paint.strokeMiterLimit = + rawMiterLimit == '' ? 4.0 : double.parse(rawMiterLimit); - final rawStrokeWidth = _getAttribute(el, 'stroke-width'); - final strokeWidth = rawStrokeWidth == "" ? 1.0 : double.parse(rawStrokeWidth); + final String rawStrokeWidth = _getAttribute(el, 'stroke-width'); + paint.strokeWidth = rawStrokeWidth == '' ? 1.0 : double.parse(rawStrokeWidth); // TODO: Dash patterns not currently supported - if (_getAttribute(el, 'stroke-dashoffset') != "" || - _getAttribute(el, 'stroke-dasharray') != "") { + if (_getAttribute(el, 'stroke-dashoffset') != '' || + _getAttribute(el, 'stroke-dasharray') != '') { print('Warning: Dash patterns not currently supported'); } - return new Paint() - ..color = stroke - ..style = PaintingStyle.stroke - ..strokeWidth = strokeWidth - ..strokeCap = strokeCap - ..strokeJoin = strokeJoin - ..strokeMiterLimit = miterLimit; + return paint; } Paint parseFill(XmlElement el, Size size, Map paintServers, {bool isShape = true}) { final rawFill = _getAttribute(el, 'fill'); - if (rawFill == "") { + if (rawFill == '') { if (isShape) { return new Paint() ..color = colorBlack @@ -164,10 +169,10 @@ Paint parseFill(XmlElement el, Size size, Map paintServers, } var rawOpacity = _getAttribute(el, 'fill-opacity'); - if (rawOpacity == "") { + if (rawOpacity == '') { rawOpacity = _getAttribute(el, 'opacity'); } - final opacity = rawOpacity == "" + final opacity = rawOpacity == '' ? rawFill == 'none' ? 0.0 : 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 6e87d60448b1..cf708363ec54 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -28,10 +28,12 @@ final Map _shapes = { new DrawableSvgShape.fromSvgLine(el, paintServers), }; +/// An SVG Shape element that will be drawn to the canvas. class DrawableSvgShape extends DrawableShape { const DrawableSvgShape(Path path, Size size, {Paint stroke, Paint fill}) : super(path, size, stroke: stroke, fill: fill); + /// Applies the transformation in the @transform attribute to the path. static Path transformPath(Path path, XmlElement el) { assert(path != null); assert(el != null); @@ -47,13 +49,14 @@ class DrawableSvgShape extends DrawableShape { static _createDrawable(Path path, Size size, Map paintServers, XmlElement el) { - final stroke = parseStroke(el); + final stroke = parseStroke(el, size, paintServers); final fill = parseFill(el, size, paintServers); return new DrawableSvgShape(transformPath(path, el), size, stroke: stroke, fill: fill); } + /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgCircle( XmlElement el, Map paintServers) { final cx = double.parse(el.getAttribute('cx')); @@ -65,6 +68,7 @@ class DrawableSvgShape extends DrawableShape { return _createDrawable(path, oval.size, paintServers, el); } + /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgPath( XmlElement el, Map paintServers) { final d = el.getAttribute('d'); @@ -72,6 +76,7 @@ class DrawableSvgShape extends DrawableShape { return _createDrawable(path, path.getBounds().size, paintServers, el); } + /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgRect( XmlElement el, Map paintServers) { final double x = double.parse(el.getAttribute('x')); @@ -84,7 +89,7 @@ class DrawableSvgShape extends DrawableShape { rxRaw ??= ryRaw; ryRaw ??= rxRaw; - if ((rxRaw != null && rxRaw != "")) { + if ((rxRaw != null && rxRaw != '')) { final double rx = double.parse(rxRaw); final double ry = double.parse(ryRaw); @@ -100,6 +105,7 @@ class DrawableSvgShape extends DrawableShape { return _createDrawable(path, rect.size, paintServers, el); } + /// Creates a [DrawableSvgShape] from an SVG or element. factory DrawableSvgShape.fromSvgPolygonOrLine( XmlElement el, Map paintServers) { final path = parseSvgPathData('M' + el.getAttribute('points') + 'z'); @@ -107,6 +113,7 @@ class DrawableSvgShape extends DrawableShape { return _createDrawable(path, path.getBounds().size, paintServers, el); } + /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgEllipse( XmlElement el, Map paintServers) { final cx = double.parse(el.getAttribute('cx')); @@ -119,6 +126,7 @@ class DrawableSvgShape extends DrawableShape { return _createDrawable(new Path()..addOval(r), r.size, paintServers, el); } + /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgLine( XmlElement el, Map paintServers) { final x1 = double.parse(el.getAttribute('x1')); @@ -133,6 +141,9 @@ class DrawableSvgShape extends DrawableShape { } } +/// Creates a [Drawable] from an SVG or shape element. Also handles parsing and gradients. +/// +/// If an unsupported element is encountered, it will be created as a [DrawableNoop]. Drawable parseSvgElement( XmlElement el, Map paintServers, Size size) { final SvgShapeFactory shapeFn = _shapes[el.name.local]; @@ -151,6 +162,7 @@ Drawable parseSvgElement( return new DrawableNoop(el.name.local); } +/// Parses an SVG element. Drawable parseSvgGroup( XmlElement el, Map paintServers, Size size) { final List children = []; @@ -165,7 +177,7 @@ Drawable parseSvgGroup( final Matrix4 transform = parseTransform(el.getAttribute('transform')); final Paint fill = parseFill(el, size, paintServers, isShape: false); - final Paint stroke = parseStroke(el); + final Paint stroke = parseStroke(el, size, paintServers); return new DrawableGroup( children, diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index a3f11c635180..a3036be5bdf2 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -66,6 +66,7 @@ class DrawableRoot implements Drawable { } } +/// Represents an element that is not rendered and has no chidlren. class DrawableNoop implements Drawable { final String name; const DrawableNoop(this.name); @@ -79,6 +80,7 @@ class DrawableNoop implements Drawable { } } +/// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. class DrawableGroup implements Drawable { final List children; final Paint stroke; @@ -113,6 +115,7 @@ class DrawableGroup implements Drawable { } } +/// Represents a drawing element that will be rendered to the canvas. class DrawableShape implements Drawable { final Paint stroke; final Paint fill; @@ -137,6 +140,7 @@ class DrawableShape implements Drawable { } } +/// A [CustomPainter] that can render a [DrawableRoot] to a [Canvas]. class VectorPainter extends CustomPainter { final DrawableRoot drawable; final bool _clipToViewBox; @@ -162,5 +166,4 @@ class VectorPainter extends CustomPainter { @override bool shouldRepaint(VectorPainter oldPainter) => true; - // _rawSvg != null && oldPainter._rawSvg != _rawSvg; } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 81a98e1e83c3..bedb9e789cba 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -13,6 +13,7 @@ import 'src/svg/xml_parsers.dart'; enum PaintLocation { Foreground, Background } +/// Handles rendering [Drawables] to a canvas. class VectorDrawableImage extends StatelessWidget { final Size size; final Future future; @@ -50,6 +51,7 @@ class VectorDrawableImage extends StatelessWidget { } } +/// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. class SvgImage extends VectorDrawableImage { SvgImage._(Future future, Size size, {bool clipToViewBox, Key key, PaintLocation paintLocation}) @@ -92,7 +94,7 @@ class SvgImage extends VectorDrawableImage { bool clipToViewBox = true, PaintLocation paintLocation = PaintLocation.Background}) { return new SvgImage._( - loadNetworkAsset2(uri, size), + loadNetworkAsset(uri, size), size, clipToViewBox: clipToViewBox, key: key, @@ -101,6 +103,7 @@ class SvgImage extends VectorDrawableImage { } } +/// Creates a [DrawableRoot] from a string of SVG data. DrawableRoot fromSvgString(String rawSvg, Size size) { final XmlElement svg = xml.parse(rawSvg).rootElement; final Rect viewBox = parseViewBox(svg); @@ -112,6 +115,7 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { return new DrawableRoot(viewBox, children, {}); } +/// Creates a [DrawableRoot] from a bundled asset. Future loadAsset(String assetName, Size size, {AssetBundle bundle, String package}) async { bundle ??= rootBundle; @@ -123,17 +127,18 @@ Future loadAsset(String assetName, Size size, final HttpClient _httpClient = new HttpClient(); -Future loadNetworkAsset2(String url, Size size) async { +/// Creates a [DrawableRoot] from a network asset with an HTTP get request. +Future loadNetworkAsset(String url, Size size) async { final Uri uri = Uri.base.resolve(url); final HttpClientRequest request = await _httpClient.getUrl(uri); final HttpClientResponse response = await request.close(); if (response.statusCode != HttpStatus.OK) throw new HttpException('Could not get network SVG asset', uri: uri); - final String rawSvg = await consolidateHttpClientResponse(response); + final String rawSvg = await _consolidateHttpClientResponse(response); return fromSvgString(rawSvg, size); } -Future consolidateHttpClientResponse( +Future _consolidateHttpClientResponse( HttpClientResponse response) async { final Completer completer = new Completer.sync(); final StringBuffer buffer = new StringBuffer(); From 04513a69e3eeb186ecb506622e6ffae5cc86133a Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 29 Apr 2018 20:35:16 -0400 Subject: [PATCH 028/512] remove unused import --- third_party/lib/src/svg/parsers.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index 662a6cda3949..db173c214f3a 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -1,4 +1,3 @@ -import 'dart:ui'; import 'dart:math'; import 'package:vector_math/vector_math_64.dart'; From 910e6020316b73978ad10353c975bfd3d6f00ebb Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 29 Apr 2018 20:38:11 -0400 Subject: [PATCH 029/512] fix travis name --- third_party/{travis.yml => .travis.yml} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename third_party/{travis.yml => .travis.yml} (100%) diff --git a/third_party/travis.yml b/third_party/.travis.yml similarity index 100% rename from third_party/travis.yml rename to third_party/.travis.yml From 735892d0d33dd0e763f43def3ad13476a6d3dd9c Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 29 Apr 2018 20:40:32 -0400 Subject: [PATCH 030/512] use master --- third_party/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/.travis.yml b/third_party/.travis.yml index d13f731cdf4d..231ccc6f3251 100644 --- a/third_party/.travis.yml +++ b/third_party/.travis.yml @@ -10,7 +10,7 @@ addons: - libstdc++6 - fonts-droid before_script: - - git clone https://github.com/flutter/flutter.git -b beta + - git clone https://github.com/flutter/flutter.git -b master - ./flutter/bin/flutter doctor script: - ./flutter/bin/flutter test From 72714282867f8f6f30269113e841d91237948b39 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 29 Apr 2018 23:10:43 -0400 Subject: [PATCH 031/512] fix linear gradients --- third_party/assets/simple/linear_gradient.svg | 2 +- third_party/lib/main.dart | 40 ++++++++++--------- third_party/lib/src/svg/colors.dart | 2 +- third_party/lib/src/svg/xml_parsers.dart | 32 +++++++++------ third_party/lib/src/svg_parser.dart | 40 +++++++++---------- third_party/lib/src/vector_painter.dart | 14 +++---- third_party/lib/svg.dart | 7 +++- 7 files changed, 75 insertions(+), 62 deletions(-) diff --git a/third_party/assets/simple/linear_gradient.svg b/third_party/assets/simple/linear_gradient.svg index c1d492339ac3..c0d45cdc5094 100644 --- a/third_party/assets/simple/linear_gradient.svg +++ b/third_party/assets/simple/linear_gradient.svg @@ -1,6 +1,6 @@ - + diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 94b352a96a69..79216e285e20 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -5,27 +5,27 @@ const List assetNames = const [ 'assets/flutter_logo.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', - 'assets/simple/rect_rrect.svg', - 'assets/w3samples/aa.svg', - 'assets/w3samples/alphachannel.svg', - 'assets/deborah_ufw/new-action-expander.svg', - 'assets/deborah_ufw/new-camera.svg', - 'assets/deborah_ufw/new-gif-button.svg', - 'assets/deborah_ufw/new-gif.svg', - 'assets/deborah_ufw/new-image.svg', - 'assets/deborah_ufw/new-mention.svg', - 'assets/deborah_ufw/new-pause-button.svg', - 'assets/deborah_ufw/new-play-button.svg', - 'assets/deborah_ufw/new-send-circle.svg', - 'assets/deborah_ufw/numeric_25.svg', - 'assets/simple/ellipse.svg', - 'assets/simple/nested_group.svg', - 'assets/wikimedia/Ghostscript_Tiger.svg', + // 'assets/simple/rect_rrect.svg', + // 'assets/w3samples/aa.svg', + // 'assets/w3samples/alphachannel.svg', + // 'assets/deborah_ufw/new-action-expander.svg', + // 'assets/deborah_ufw/new-camera.svg', + // 'assets/deborah_ufw/new-gif-button.svg', + // 'assets/deborah_ufw/new-gif.svg', + // 'assets/deborah_ufw/new-image.svg', + // 'assets/deborah_ufw/new-mention.svg', + // 'assets/deborah_ufw/new-pause-button.svg', + // 'assets/deborah_ufw/new-play-button.svg', + // 'assets/deborah_ufw/new-send-circle.svg', + // 'assets/deborah_ufw/numeric_25.svg', + // 'assets/simple/ellipse.svg', + // 'assets/simple/nested_group.svg', + // 'assets/wikimedia/Ghostscript_Tiger.svg', ]; const List uriNames = const [ // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' + // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' ]; void main() => runApp(new MyApp()); @@ -59,7 +59,7 @@ class _MyHomePageState extends State { @override void initState() { super.initState(); - _dimension = 100.0; + _dimension = 365.0; assetNames.forEach((assetName) { _painters.add( new SvgImage.asset( @@ -90,7 +90,9 @@ class _MyHomePageState extends State { min: 5.0, max: MediaQuery.of(context).size.width - 10.0, value: _dimension, - onChanged: (val) => setState(() => _dimension = val)), + onChanged: (val) { + setState(() => _dimension = val); + }), // new FlutterLogo(size: _dimension), new Expanded( child: new GridView.extent( diff --git a/third_party/lib/src/svg/colors.dart b/third_party/lib/src/svg/colors.dart index d2c01e3a2a46..e8fb9ee62352 100644 --- a/third_party/lib/src/svg/colors.dart +++ b/third_party/lib/src/svg/colors.dart @@ -5,7 +5,7 @@ const colorBlack = const Color.fromARGB(255, 0, 0, 0); /// Converts a SVG Color String (either a # prefixed color string or a named color) to a [Color]. Color parseColor(String colorString) { if (colorString == null || colorString.length == 0) { - return const Color.fromARGB(255, 0, 0, 0); + return colorBlack; } if (colorString[0] == '#') { diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index e8c69506393a..cc67d71e7ade 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -36,13 +36,12 @@ Rect parseViewBox(XmlElement svg) { } /// Parses a element, extracting and (TODO) elements into the `paintServers` map. -void parseDefs( - XmlElement el, Map paintServers, Size size) { +void parseDefs(XmlElement el, Map paintServers) { el.children.forEach((XmlNode def) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { paintServers['url(#${def.getAttribute('id')})'] = - (size) => parseGradient(def, size); + (Rect size) => parseGradient(def, size); } } }); @@ -64,14 +63,22 @@ double _parseDecimalOrPercentage(String val) { } /// Parses an SVG element into a [Paint]. -Paint parseLinearGradient(XmlElement el, Size size) { +Paint parseLinearGradient(XmlElement el, Rect bounds) { final double x1 = _parseDecimalOrPercentage(_getAttribute(el, 'x1', '0%')); final double x2 = _parseDecimalOrPercentage(_getAttribute(el, 'x2', '100%')); final double y1 = _parseDecimalOrPercentage(_getAttribute(el, 'y1', '0%')); final double y2 = _parseDecimalOrPercentage(_getAttribute(el, 'y2', '0%')); - final Offset from = new Offset(size.width * x1, size.height * y1); - final Offset to = new Offset(size.width * x2, size.height * y2); + final Offset from = new Offset( + bounds.left + (bounds.width * x1), + bounds.left + (bounds.height * y1), + ); + final Offset to = new Offset( + bounds.left + (bounds.width * x2), + bounds.left + (bounds.height * y2), + ); + + print('$bounds ${bounds.size} $from $to'); final stops = el.findElements('stop').toList(); final Gradient gradient = new Gradient.linear( from, @@ -91,9 +98,9 @@ Paint parseLinearGradient(XmlElement el, Size size) { } /// Parses a or into a [Paint]. -Paint parseGradient(XmlElement el, Size size) { +Paint parseGradient(XmlElement el, Rect bounds) { if (el.name.local == 'linearGradient') { - return parseLinearGradient(el, size); + return parseLinearGradient(el, bounds); } else if (el.name.local == 'radialGradient') { return new Paint()..color = new Color(0xFFABCDEF); } @@ -102,14 +109,14 @@ Paint parseGradient(XmlElement el, Size size) { /// Parses a @stroke attribute into a [Paint]. Paint parseStroke( - XmlElement el, Size size, Map paintServers) { + XmlElement el, Rect bounds, Map paintServers) { final rawStroke = _getAttribute(el, 'stroke'); if (rawStroke == '') { return null; } if (rawStroke.startsWith('url')) { - return paintServers[rawStroke](size); + return paintServers[rawStroke](bounds); } var rawOpacity = _getAttribute(el, 'stroke-opacity'); if (rawOpacity == '') { @@ -151,7 +158,8 @@ Paint parseStroke( return paint; } -Paint parseFill(XmlElement el, Size size, Map paintServers, +Paint parseFill( + XmlElement el, Rect bounds, Map paintServers, {bool isShape = true}) { final rawFill = _getAttribute(el, 'fill'); if (rawFill == '') { @@ -165,7 +173,7 @@ Paint parseFill(XmlElement el, Size size, Map paintServers, } if (rawFill.startsWith('url')) { - return paintServers[rawFill](size); + return paintServers[rawFill](bounds); } var rawOpacity = _getAttribute(el, 'fill-opacity'); diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index cf708363ec54..6bdf1c2bab27 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -30,8 +30,8 @@ final Map _shapes = { /// An SVG Shape element that will be drawn to the canvas. class DrawableSvgShape extends DrawableShape { - const DrawableSvgShape(Path path, Size size, {Paint stroke, Paint fill}) - : super(path, size, stroke: stroke, fill: fill); + const DrawableSvgShape(Path path, Rect bounds, {Paint stroke, Paint fill}) + : super(path, bounds, stroke: stroke, fill: fill); /// Applies the transformation in the @transform attribute to the path. static Path transformPath(Path path, XmlElement el) { @@ -47,12 +47,12 @@ class DrawableSvgShape extends DrawableShape { } } - static _createDrawable(Path path, Size size, + static _createDrawable(Path path, Rect bounds, Map paintServers, XmlElement el) { - final stroke = parseStroke(el, size, paintServers); - final fill = parseFill(el, size, paintServers); + final stroke = parseStroke(el, bounds, paintServers); + final fill = parseFill(el, bounds, paintServers); - return new DrawableSvgShape(transformPath(path, el), size, + return new DrawableSvgShape(transformPath(path, el), bounds, stroke: stroke, fill: fill); } @@ -65,7 +65,7 @@ class DrawableSvgShape extends DrawableShape { final oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); final path = new Path()..addOval(oval); - return _createDrawable(path, oval.size, paintServers, el); + return _createDrawable(path, oval, paintServers, el); } /// Creates a [DrawableSvgShape] from an SVG element. @@ -73,7 +73,7 @@ class DrawableSvgShape extends DrawableShape { XmlElement el, Map paintServers) { final d = el.getAttribute('d'); final Path path = parseSvgPathData(d); - return _createDrawable(path, path.getBounds().size, paintServers, el); + return _createDrawable(path, path.getBounds(), paintServers, el); } /// Creates a [DrawableSvgShape] from an SVG element. @@ -95,14 +95,14 @@ class DrawableSvgShape extends DrawableShape { return _createDrawable( new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)), - rect.size, + rect, paintServers, el, ); } final path = new Path()..addRect(rect); - return _createDrawable(path, rect.size, paintServers, el); + return _createDrawable(path, rect, paintServers, el); } /// Creates a [DrawableSvgShape] from an SVG or element. @@ -110,7 +110,7 @@ class DrawableSvgShape extends DrawableShape { XmlElement el, Map paintServers) { final path = parseSvgPathData('M' + el.getAttribute('points') + 'z'); - return _createDrawable(path, path.getBounds().size, paintServers, el); + return _createDrawable(path, path.getBounds(), paintServers, el); } /// Creates a [DrawableSvgShape] from an SVG element. @@ -123,7 +123,7 @@ class DrawableSvgShape extends DrawableShape { Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); - return _createDrawable(new Path()..addOval(r), r.size, paintServers, el); + return _createDrawable(new Path()..addOval(r), r, paintServers, el); } /// Creates a [DrawableSvgShape] from an SVG element. @@ -137,7 +137,7 @@ class DrawableSvgShape extends DrawableShape { final path = new Path() ..moveTo(x1, x2) ..lineTo(y1, y2); - return _createDrawable(path, path.getBounds().size, paintServers, el); + return _createDrawable(path, path.getBounds(), paintServers, el); } } @@ -145,14 +145,14 @@ class DrawableSvgShape extends DrawableShape { /// /// If an unsupported element is encountered, it will be created as a [DrawableNoop]. Drawable parseSvgElement( - XmlElement el, Map paintServers, Size size) { + XmlElement el, Map paintServers, Rect bounds) { final SvgShapeFactory shapeFn = _shapes[el.name.local]; if (shapeFn != null) { return shapeFn(el, paintServers); } else if (el.name.local == 'defs') { - parseDefs(el, paintServers, size); + parseDefs(el, paintServers); } else if (el.name.local == 'g') { - return parseSvgGroup(el, paintServers, size); + return parseSvgGroup(el, paintServers, bounds); } if (el.name.local == 'svg') { throw new UnsupportedError( @@ -164,11 +164,11 @@ Drawable parseSvgElement( /// Parses an SVG element. Drawable parseSvgGroup( - XmlElement el, Map paintServers, Size size) { + XmlElement el, Map paintServers, Rect bounds) { final List children = []; el.children.forEach((child) { if (child is XmlElement) { - final Drawable el = parseSvgElement(child, paintServers, size); + final Drawable el = parseSvgElement(child, paintServers, bounds); if (el != null) { children.add(el); } @@ -176,8 +176,8 @@ Drawable parseSvgGroup( }); final Matrix4 transform = parseTransform(el.getAttribute('transform')); - final Paint fill = parseFill(el, size, paintServers, isShape: false); - final Paint stroke = parseStroke(el, size, paintServers); + final Paint fill = parseFill(el, bounds, paintServers, isShape: false); + final Paint stroke = parseStroke(el, bounds, paintServers); return new DrawableGroup( children, diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index a3036be5bdf2..c43f2db2659b 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -3,7 +3,7 @@ import 'dart:typed_data'; import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart'; -typedef Paint PaintServer(Size size); +typedef Paint PaintServer(Rect bounds); /// Base interface for vector drawing. @immutable @@ -75,9 +75,7 @@ class DrawableNoop implements Drawable { bool get isVisible => false; @override - void draw(Canvas canvas, [Paint parentPaint]) { - print('Attempted to draw $name'); - } + void draw(Canvas canvas, [Paint parentPaint]) {} } /// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. @@ -120,14 +118,14 @@ class DrawableShape implements Drawable { final Paint stroke; final Paint fill; final Path path; - final Size size; + final Rect bounds; - const DrawableShape(this.path, this.size, {this.stroke, this.fill}) + const DrawableShape(this.path, this.bounds, {this.stroke, this.fill}) : assert(path != null), - assert(size != null); + assert(bounds != null); @override - bool get isVisible => !size.isEmpty && (stroke != null || fill != null); + bool get isVisible => !bounds.isEmpty && (stroke != null || fill != null); @override void draw(Canvas canvas, [Paint parentPaint]) { diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index bedb9e789cba..07f83452b5da 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -110,7 +110,11 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { Map paintServers = {}; final List children = svg.children .where((XmlNode child) => child is XmlElement) - .map((XmlNode child) => parseSvgElement(child, paintServers, size)) + .map((XmlNode child) => parseSvgElement( + child, + paintServers, + new Rect.fromPoints( + Offset.zero, new Offset(size.width, size.height)))) .toList(); return new DrawableRoot(viewBox, children, {}); } @@ -146,6 +150,7 @@ Future _consolidateHttpClientResponse( response.transform(utf8.decoder).listen((String chunk) { buffer.write(chunk); }, onDone: () { + // There's a bug right now where sometimes GZIP encoded payloads aren't coming all the way through.. print(buffer.toString()); completer.complete(buffer.toString()); }, onError: completer.completeError, cancelOnError: true); From 58a3fe62357b13d4bf0547230103139aefd14756 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 29 Apr 2018 23:16:26 -0400 Subject: [PATCH 032/512] remove unintended comment outs, remove debug printing, rename var --- third_party/lib/main.dart | 34 ++++++++++++------------ third_party/lib/src/svg/xml_parsers.dart | 3 +-- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 79216e285e20..73ab6f29ffb1 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -5,27 +5,27 @@ const List assetNames = const [ 'assets/flutter_logo.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', - // 'assets/simple/rect_rrect.svg', - // 'assets/w3samples/aa.svg', - // 'assets/w3samples/alphachannel.svg', - // 'assets/deborah_ufw/new-action-expander.svg', - // 'assets/deborah_ufw/new-camera.svg', - // 'assets/deborah_ufw/new-gif-button.svg', - // 'assets/deborah_ufw/new-gif.svg', - // 'assets/deborah_ufw/new-image.svg', - // 'assets/deborah_ufw/new-mention.svg', - // 'assets/deborah_ufw/new-pause-button.svg', - // 'assets/deborah_ufw/new-play-button.svg', - // 'assets/deborah_ufw/new-send-circle.svg', - // 'assets/deborah_ufw/numeric_25.svg', - // 'assets/simple/ellipse.svg', - // 'assets/simple/nested_group.svg', - // 'assets/wikimedia/Ghostscript_Tiger.svg', + 'assets/simple/rect_rrect.svg', + 'assets/w3samples/aa.svg', + 'assets/w3samples/alphachannel.svg', + 'assets/deborah_ufw/new-action-expander.svg', + 'assets/deborah_ufw/new-camera.svg', + 'assets/deborah_ufw/new-gif-button.svg', + 'assets/deborah_ufw/new-gif.svg', + 'assets/deborah_ufw/new-image.svg', + 'assets/deborah_ufw/new-mention.svg', + 'assets/deborah_ufw/new-pause-button.svg', + 'assets/deborah_ufw/new-play-button.svg', + 'assets/deborah_ufw/new-send-circle.svg', + 'assets/deborah_ufw/numeric_25.svg', + 'assets/simple/ellipse.svg', + 'assets/simple/nested_group.svg', + 'assets/wikimedia/Ghostscript_Tiger.svg', ]; const List uriNames = const [ // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' ]; void main() => runApp(new MyApp()); diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index cc67d71e7ade..5a5d09e7f6eb 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -41,7 +41,7 @@ void parseDefs(XmlElement el, Map paintServers) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { paintServers['url(#${def.getAttribute('id')})'] = - (Rect size) => parseGradient(def, size); + (Rect bounds) => parseGradient(def, bounds); } } }); @@ -78,7 +78,6 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { bounds.left + (bounds.height * y2), ); - print('$bounds ${bounds.size} $from $to'); final stops = el.findElements('stop').toList(); final Gradient gradient = new Gradient.linear( from, From 9cfd0ddf8b18efe94d131414efc0866c6c79500f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 30 Apr 2018 00:37:50 -0400 Subject: [PATCH 033/512] initial radial gradient implementation --- third_party/assets/simple/radial_gradient.svg | 26 ++++++++++++++ third_party/lib/main.dart | 1 + third_party/lib/src/svg/xml_parsers.dart | 35 ++++++++++++++++++- third_party/pubspec.yaml | 1 + 4 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 third_party/assets/simple/radial_gradient.svg diff --git a/third_party/assets/simple/radial_gradient.svg b/third_party/assets/simple/radial_gradient.svg new file mode 100644 index 000000000000..42bcbd6e9038 --- /dev/null +++ b/third_party/assets/simple/radial_gradient.svg @@ -0,0 +1,26 @@ + + + + Example radgrad01 - fill a rectangle by referencing a + radial gradient paint server + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 73ab6f29ffb1..fbb073abf76a 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -5,6 +5,7 @@ const List assetNames = const [ 'assets/flutter_logo.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', + 'assets/simple/radial_gradient.svg', 'assets/simple/rect_rrect.svg', 'assets/w3samples/aa.svg', 'assets/w3samples/alphachannel.svg', diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 5a5d09e7f6eb..82d546a27908 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -96,12 +96,45 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { return new Paint()..shader = gradient; } +/// Parses a into a [Paint]. +Paint parseRadialGradient(XmlElement el, Rect bounds) { + final String rawCx = _getAttribute(el, 'cx', '50%'); + final String rawCy = _getAttribute(el, 'cy', '50%'); + final double cx = _parseDecimalOrPercentage(rawCx); + final double cy = _parseDecimalOrPercentage(rawCy); + final double r = _parseDecimalOrPercentage(_getAttribute(el, 'r', '50%')); + final double fx = _parseDecimalOrPercentage(_getAttribute(el, 'fx', rawCx)); + final double fy = _parseDecimalOrPercentage(_getAttribute(el, 'fy', rawCy)); + + if (fx != cx || fy != cy) { + throw new UnsupportedError( + 'Focal points not supported by this implementation'); + } + + final stops = el.findElements('stop').toList(); + final Gradient gradient = new Gradient.radial( + new Offset(cx, cy), + r, + stops.map((stop) { + final String rawOpacity = _getAttribute(stop, 'stop-opacity', '1'); + return parseColor(_getAttribute(stop, 'stop-color')) + .withOpacity(double.parse(rawOpacity)); + }).toList(), + stops.map((stop) { + final String rawOffset = _getAttribute(stop, 'offset'); + return _parseDecimalOrPercentage(rawOffset); + }).toList(), + ); + + return new Paint()..shader = gradient; +} + /// Parses a or into a [Paint]. Paint parseGradient(XmlElement el, Rect bounds) { if (el.name.local == 'linearGradient') { return parseLinearGradient(el, bounds); } else if (el.name.local == 'radialGradient') { - return new Paint()..color = new Color(0xFFABCDEF); + return parseRadialGradient(el, bounds); } throw new StateError('Unknown gradient type ${el.name.local}'); } diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 2a705a0d571e..73801f2bfd8a 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -48,6 +48,7 @@ flutter: - assets/simple/rect_rrect.svg - assets/simple/linear_gradient.svg - assets/simple/linear_gradient_2.svg + - assets/simple/radial_gradient.svg - assets/wikimedia/Ghostscript_Tiger.svg # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg From 19ea0282dc4a4c007d50a233f4a6f143a3fee781 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 30 Apr 2018 20:58:05 -0400 Subject: [PATCH 034/512] light refactoring of svg, add initial android drawable support --- .../assets/android_vd/battery_charging.xml | 22 ++++ third_party/lib/avd.dart | 118 ++++++++++++++++++ third_party/lib/main.dart | 8 +- third_party/lib/src/avd/xml_parsers.dart | 107 ++++++++++++++++ third_party/lib/src/avd_parser.dart | 72 +++++++++++ third_party/lib/src/svg/xml_parsers.dart | 73 ++++++----- third_party/lib/src/svg_parser.dart | 29 ++--- third_party/lib/src/utilities/xml.dart | 8 ++ third_party/lib/src/vector_painter.dart | 38 ++++-- third_party/lib/svg.dart | 43 +------ third_party/lib/vector_drawable.dart | 46 +++++++ third_party/pubspec.yaml | 1 + 12 files changed, 460 insertions(+), 105 deletions(-) create mode 100644 third_party/assets/android_vd/battery_charging.xml create mode 100644 third_party/lib/avd.dart create mode 100644 third_party/lib/src/avd/xml_parsers.dart create mode 100644 third_party/lib/src/avd_parser.dart create mode 100644 third_party/lib/src/utilities/xml.dart create mode 100644 third_party/lib/vector_drawable.dart diff --git a/third_party/assets/android_vd/battery_charging.xml b/third_party/assets/android_vd/battery_charging.xml new file mode 100644 index 000000000000..61628a7602aa --- /dev/null +++ b/third_party/assets/android_vd/battery_charging.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart new file mode 100644 index 000000000000..ef873fcda10e --- /dev/null +++ b/third_party/lib/avd.dart @@ -0,0 +1,118 @@ +import 'dart:async'; +import 'dart:io'; +import 'dart:convert'; + +import 'package:flutter/services.dart' show rootBundle, AssetBundle; +import 'package:flutter/widgets.dart'; +import 'package:xml/xml.dart' hide parse; +import 'package:xml/xml.dart' as xml show parse; + +import 'vector_drawable.dart'; +import 'src/vector_painter.dart'; +import 'src/avd_parser.dart'; +import 'src/avd/xml_parsers.dart'; + +/// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. +class AvdImage extends VectorDrawableImage { + AvdImage._(Future future, Size size, + {bool clipToViewBox, Key key, PaintLocation paintLocation}) + : super(future, size, + clipToViewBox: clipToViewBox, + key: key, + paintLocation: paintLocation); + + factory AvdImage.fromString(String svg, Size size, + {Key key, + bool clipToViewBox = true, + PaintLocation paintLocation = PaintLocation.Background}) { + return new AvdImage._( + new Future.value(fromAvdString(svg, size)), + size, + clipToViewBox: clipToViewBox, + key: key, + paintLocation: paintLocation, + ); + } + + factory AvdImage.asset(String assetName, Size size, + {Key key, + AssetBundle bundle, + String package, + bool clipToViewBox = true, + PaintLocation paintLocation = PaintLocation.Background}) { + return new AvdImage._( + loadAsset(assetName, size, bundle: bundle, package: package), + size, + clipToViewBox: clipToViewBox, + key: key, + paintLocation: paintLocation, + ); + } + + factory AvdImage.network(String uri, Size size, + {Map headers, + Key key, + bool clipToViewBox = true, + PaintLocation paintLocation = PaintLocation.Background}) { + return new AvdImage._( + loadNetworkAsset(uri, size), + size, + clipToViewBox: clipToViewBox, + key: key, + paintLocation: paintLocation, + ); + } +} + +/// Creates a [DrawableRoot] from a string of SVG data. +DrawableRoot fromAvdString(String rawSvg, Size size) { + final XmlElement svg = xml.parse(rawSvg).rootElement; + final Rect viewBox = parseViewBox(svg); + final List children = svg.children + .where((XmlNode child) => child is XmlElement) + .map((XmlNode child) => parseAvdElement( + child, + new Rect.fromPoints( + Offset.zero, new Offset(size.width, size.height)))) + .toList(); + return new DrawableRoot(viewBox, children, {}); +} + +/// Creates a [DrawableRoot] from a bundled asset. +Future loadAsset(String assetName, Size size, + {AssetBundle bundle, String package}) async { + bundle ??= rootBundle; + final String rawSvg = await bundle.loadString( + package == null ? assetName : 'packages/$package/$assetName', + ); + return fromAvdString(rawSvg, size); +} + +final HttpClient _httpClient = new HttpClient(); + +/// Creates a [DrawableRoot] from a network asset with an HTTP get request. +Future loadNetworkAsset(String url, Size size) async { + final Uri uri = Uri.base.resolve(url); + final HttpClientRequest request = await _httpClient.getUrl(uri); + final HttpClientResponse response = await request.close(); + if (response.statusCode != HttpStatus.OK) + throw new HttpException('Could not get network SVG asset', uri: uri); + final String rawSvg = await _consolidateHttpClientResponse(response); + return fromAvdString(rawSvg, size); +} + +Future _consolidateHttpClientResponse( + HttpClientResponse response) async { + final Completer completer = new Completer.sync(); + final StringBuffer buffer = new StringBuffer(); + + response.transform(utf8.decoder).listen((String chunk) { + buffer.write(chunk); + }, onDone: () { + // There's a bug right now where sometimes GZIP encoded payloads aren't coming all the way through.. + print(buffer.toString()); + completer.complete(buffer.toString()); + }, onError: completer.completeError, cancelOnError: true); + + return completer.future; +} diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index fbb073abf76a..a8b1eb90263e 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/avd.dart'; +import 'package:flutter_svg/vector_drawable.dart'; import 'package:flutter_svg/svg.dart'; const List assetNames = const [ @@ -54,13 +56,17 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - List _painters = new List(); + List _painters = new List(); double _dimension; @override void initState() { super.initState(); _dimension = 365.0; + + _painters.add(new AvdImage.asset('assets/android_vd/battery_charging.xml', + new Size(_dimension, _dimension))); + assetNames.forEach((assetName) { _painters.add( new SvgImage.asset( diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart new file mode 100644 index 000000000000..43fcec1898b2 --- /dev/null +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -0,0 +1,107 @@ +import 'dart:math'; +import 'dart:ui'; + +import 'package:vector_math/vector_math_64.dart'; +import 'package:xml/xml.dart'; + +import '../utilities/xml.dart'; +import '../svg/colors.dart'; + +const String androidNS = 'http://schemas.android.com/apk/res/android'; + +/// Parses an AVD @android:viewportWidth and @android:viewportHeight attributes to a [Rect]. +Rect parseViewBox(XmlElement el) { + final String rawWidth = getAttribute(el, 'viewportWidth', '', androidNS); + final String rawHeight = getAttribute(el, 'viewportHeight', '', androidNS); + if (rawWidth == '' || rawHeight == '') { + return Rect.zero; + } + final double width = double.parse(rawWidth); + final double height = double.parse(rawHeight); + return new Rect.fromLTWH(0.0, 0.0, width, height); +} + +Matrix4 parseTransform(XmlElement el) { + double rotation = double.parse(getAttribute(el, 'rotation', '0', androidNS)); + double pivotX = double.parse(getAttribute(el, 'pivotX', '0', androidNS)); + double pivotY = double.parse(getAttribute(el, 'pivotY', '0', androidNS)); + double scaleX = double.parse(getAttribute(el, 'scaleX', '1', androidNS)); + double scaleY = double.parse(getAttribute(el, 'scaleY', '1', androidNS)); + double translateX = + double.parse(getAttribute(el, 'translateX', '0', androidNS)); + double translateY = + double.parse(getAttribute(el, 'translateY', '0', androidNS)); + + print('$pivotX $pivotY'); + return new Matrix4.identity() + ..translate(pivotX, pivotY) + ..rotateZ(rotation * pi / 180) + ..scale(scaleX, scaleY) + ..translate(-pivotX + translateX, -pivotY + translateY); +} + +Paint parseStroke(XmlElement el, Rect bounds) { + final String rawStroke = getAttribute(el, 'strokeColor', null, androidNS); + if (rawStroke == null) { + return null; + } + return new Paint() + ..style = PaintingStyle.stroke + ..color = parseColor(rawStroke) + .withOpacity(double.parse(getAttribute(el, 'strokeAlpha', '1'))) + ..strokeWidth = + double.parse(getAttribute(el, 'strokeWidth', '0', androidNS)) + ..strokeCap = parseStrokeCap(el) + ..strokeJoin = parseStrokeJoin(el) + ..strokeMiterLimit = parseMiterLimit(el); +} + +double parseMiterLimit(XmlElement el) { + return double.parse(getAttribute(el, 'strokeMiterLimit', '4', androidNS)); +} + +StrokeJoin parseStrokeJoin(XmlElement el) { + final String rawStrokeJoin = + getAttribute(el, 'strokeLineJoin', 'miter', androidNS); + switch (rawStrokeJoin) { + case 'miter': + return StrokeJoin.miter; + case 'bevel': + return StrokeJoin.bevel; + case 'round': + return StrokeJoin.round; + default: + return StrokeJoin.miter; + } +} + +StrokeCap parseStrokeCap(XmlElement el) { + final String rawStrokeCap = + getAttribute(el, 'strokeLineCap', 'butt', androidNS); + switch (rawStrokeCap) { + case 'butt': + return StrokeCap.butt; + case 'round': + return StrokeCap.round; + case 'square': + return StrokeCap.square; + default: + return StrokeCap.butt; + } +} + +Paint parseFill(XmlElement el, Rect bounds) { + final String rawFill = getAttribute(el, 'fillColor', null, androidNS); + if (rawFill == null) { + return null; + } + return new Paint() + ..style = PaintingStyle.fill + ..color = parseColor(rawFill) + .withOpacity(double.parse(getAttribute(el, 'fillAlpha', '1'))); +} + +PathFillType parsePathFillType(XmlElement el) { + final String rawFillType = getAttribute(el, 'fillType', 'nonZero', androidNS); + return rawFillType == 'nonZero' ? PathFillType.nonZero : PathFillType.evenOdd; +} diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart new file mode 100644 index 000000000000..282006331e00 --- /dev/null +++ b/third_party/lib/src/avd_parser.dart @@ -0,0 +1,72 @@ +import 'dart:ui'; + +import 'package:xml/xml.dart'; +import 'package:path_drawing/path_drawing.dart'; +import 'package:vector_math/vector_math_64.dart'; + +import 'vector_painter.dart'; +import 'avd/xml_parsers.dart'; + +class DrawableAvdRoot extends DrawableRoot { + const DrawableAvdRoot( + Rect viewBox, List children, Map paintServers) + : super(viewBox, children, paintServers); +} + +/// An SVG Shape element that will be drawn to the canvas. +class DrawableAvdPath extends DrawableShape { + const DrawableAvdPath(Path path, {Paint stroke, Paint fill}) + : super(path, stroke: stroke, fill: fill); + + /// Creates a [DrawableAvdPath] from an XML element + factory DrawableAvdPath.fromXml(XmlElement el) { + final d = el.getAttribute('pathData', namespace: androidNS); + final Path path = parseSvgPathData(d); + assert(path != null); + + path.fillType = parsePathFillType(el); + final stroke = parseStroke(el, path.getBounds()); + final fill = parseFill(el, path.getBounds()); + + return new DrawableAvdPath(path, stroke: stroke, fill: fill); + } +} + +/// Creates a [Drawable] from an SVG or shape element. Also handles parsing and gradients. +/// +/// If an unsupported element is encountered, it will be created as a [DrawableNoop]. +Drawable parseAvdElement(XmlElement el, Rect bounds) { + if (el.name.local == 'path') { + return new DrawableAvdPath.fromXml(el); + } else if (el.name.local == 'group') { + return parseAvdGroup(el, bounds); + } + // TODO: clipPath + print('Unhandled element ${el.name.local}'); + return new DrawableNoop(el.name.local); +} + +/// Parses an AVD element. +Drawable parseAvdGroup(XmlElement el, Rect bounds) { + final List children = []; + el.children.forEach((child) { + if (child is XmlElement) { + final Drawable el = parseAvdElement(child, bounds); + if (el != null) { + children.add(el); + } + } + }); + + final Matrix4 transform = parseTransform(el); + + final Paint fill = parseFill(el, bounds); + final Paint stroke = parseStroke(el, bounds); + + return new DrawableGroup( + children, + transform?.storage, + stroke, + fill, + ); +} diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 82d546a27908..e41d09d4fe3f 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -3,18 +3,19 @@ import 'dart:ui'; import 'package:xml/xml.dart'; import '../vector_painter.dart'; +import '../utilities/xml.dart'; import 'colors.dart'; /// Parses an SVG @viewBox attribute (e.g. 0 0 100 100) to a [Rect]. Rect parseViewBox(XmlElement svg) { - final String viewBox = _getAttribute(svg, 'viewBox'); + final String viewBox = getAttribute(svg, 'viewBox'); if (viewBox == '') { final RegExp notDigits = new RegExp(r'[^\d\.]'); final String rawWidth = - _getAttribute(svg, 'width').replaceAll(notDigits, ''); + getAttribute(svg, 'width').replaceAll(notDigits, ''); final String rawHeight = - _getAttribute(svg, 'height').replaceAll(notDigits, ''); + getAttribute(svg, 'height').replaceAll(notDigits, ''); if (rawWidth == '' || rawHeight == '') { return Rect.zero; } @@ -47,13 +48,6 @@ void parseDefs(XmlElement el, Map paintServers) { }); } -/// Gets the attribute, trims it, and returns the attribute or default if the attribute -/// is null or ''. -String _getAttribute(XmlElement el, String name, [String def = '']) { - final String raw = el.getAttribute(name)?.trim(); - return raw == '' || raw == null ? def : raw; -} - double _parseDecimalOrPercentage(String val) { if (val.endsWith('%')) { return double.parse(val.substring(0, val.length - 1)) / 100; @@ -64,10 +58,10 @@ double _parseDecimalOrPercentage(String val) { /// Parses an SVG element into a [Paint]. Paint parseLinearGradient(XmlElement el, Rect bounds) { - final double x1 = _parseDecimalOrPercentage(_getAttribute(el, 'x1', '0%')); - final double x2 = _parseDecimalOrPercentage(_getAttribute(el, 'x2', '100%')); - final double y1 = _parseDecimalOrPercentage(_getAttribute(el, 'y1', '0%')); - final double y2 = _parseDecimalOrPercentage(_getAttribute(el, 'y2', '0%')); + final double x1 = _parseDecimalOrPercentage(getAttribute(el, 'x1', '0%')); + final double x2 = _parseDecimalOrPercentage(getAttribute(el, 'x2', '100%')); + final double y1 = _parseDecimalOrPercentage(getAttribute(el, 'y1', '0%')); + final double y2 = _parseDecimalOrPercentage(getAttribute(el, 'y2', '0%')); final Offset from = new Offset( bounds.left + (bounds.width * x1), @@ -83,12 +77,12 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { from, to, stops.map((stop) { - final String rawOpacity = _getAttribute(stop, 'stop-opacity', '1'); - return parseColor(_getAttribute(stop, 'stop-color')) + final String rawOpacity = getAttribute(stop, 'stop-opacity', '1'); + return parseColor(getAttribute(stop, 'stop-color')) .withOpacity(double.parse(rawOpacity)); }).toList(), stops.map((stop) { - final String rawOffset = _getAttribute(stop, 'offset'); + final String rawOffset = getAttribute(stop, 'offset'); return _parseDecimalOrPercentage(rawOffset); }).toList(), ); @@ -98,13 +92,13 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { /// Parses a into a [Paint]. Paint parseRadialGradient(XmlElement el, Rect bounds) { - final String rawCx = _getAttribute(el, 'cx', '50%'); - final String rawCy = _getAttribute(el, 'cy', '50%'); + final String rawCx = getAttribute(el, 'cx', '50%'); + final String rawCy = getAttribute(el, 'cy', '50%'); final double cx = _parseDecimalOrPercentage(rawCx); final double cy = _parseDecimalOrPercentage(rawCy); - final double r = _parseDecimalOrPercentage(_getAttribute(el, 'r', '50%')); - final double fx = _parseDecimalOrPercentage(_getAttribute(el, 'fx', rawCx)); - final double fy = _parseDecimalOrPercentage(_getAttribute(el, 'fy', rawCy)); + final double r = _parseDecimalOrPercentage(getAttribute(el, 'r', '50%')); + final double fx = _parseDecimalOrPercentage(getAttribute(el, 'fx', rawCx)); + final double fy = _parseDecimalOrPercentage(getAttribute(el, 'fy', rawCy)); if (fx != cx || fy != cy) { throw new UnsupportedError( @@ -116,12 +110,12 @@ Paint parseRadialGradient(XmlElement el, Rect bounds) { new Offset(cx, cy), r, stops.map((stop) { - final String rawOpacity = _getAttribute(stop, 'stop-opacity', '1'); - return parseColor(_getAttribute(stop, 'stop-color')) + final String rawOpacity = getAttribute(stop, 'stop-opacity', '1'); + return parseColor(getAttribute(stop, 'stop-color')) .withOpacity(double.parse(rawOpacity)); }).toList(), stops.map((stop) { - final String rawOffset = _getAttribute(stop, 'offset'); + final String rawOffset = getAttribute(stop, 'offset'); return _parseDecimalOrPercentage(rawOffset); }).toList(), ); @@ -142,7 +136,7 @@ Paint parseGradient(XmlElement el, Rect bounds) { /// Parses a @stroke attribute into a [Paint]. Paint parseStroke( XmlElement el, Rect bounds, Map paintServers) { - final rawStroke = _getAttribute(el, 'stroke'); + final rawStroke = getAttribute(el, 'stroke'); if (rawStroke == '') { return null; } @@ -150,9 +144,9 @@ Paint parseStroke( if (rawStroke.startsWith('url')) { return paintServers[rawStroke](bounds); } - var rawOpacity = _getAttribute(el, 'stroke-opacity'); + var rawOpacity = getAttribute(el, 'stroke-opacity'); if (rawOpacity == '') { - rawOpacity = _getAttribute(el, 'opacity'); + rawOpacity = getAttribute(el, 'opacity'); } final double opacity = rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); @@ -160,30 +154,30 @@ Paint parseStroke( ..color = parseColor(rawStroke).withOpacity(opacity) ..style = PaintingStyle.stroke; - final String rawStrokeCap = _getAttribute(el, 'stroke-linecap'); + final String rawStrokeCap = getAttribute(el, 'stroke-linecap'); paint.strokeCap = rawStrokeCap == 'null' ? StrokeCap.butt : StrokeCap.values.firstWhere( (sc) => sc.toString() == 'StrokeCap.$rawStrokeCap', orElse: () => StrokeCap.butt); - final String rawLineJoin = _getAttribute(el, 'stroke-linejoin'); + final String rawLineJoin = getAttribute(el, 'stroke-linejoin'); paint.strokeJoin = rawLineJoin == '' ? StrokeJoin.miter : StrokeJoin.values.firstWhere( (sj) => sj.toString() == 'StrokeJoin.$rawLineJoin', orElse: () => StrokeJoin.miter); - final String rawMiterLimit = _getAttribute(el, 'stroke-miterlimit'); + final String rawMiterLimit = getAttribute(el, 'stroke-miterlimit'); paint.strokeMiterLimit = rawMiterLimit == '' ? 4.0 : double.parse(rawMiterLimit); - final String rawStrokeWidth = _getAttribute(el, 'stroke-width'); + final String rawStrokeWidth = getAttribute(el, 'stroke-width'); paint.strokeWidth = rawStrokeWidth == '' ? 1.0 : double.parse(rawStrokeWidth); // TODO: Dash patterns not currently supported - if (_getAttribute(el, 'stroke-dashoffset') != '' || - _getAttribute(el, 'stroke-dasharray') != '') { + if (getAttribute(el, 'stroke-dashoffset') != '' || + getAttribute(el, 'stroke-dasharray') != '') { print('Warning: Dash patterns not currently supported'); } @@ -193,7 +187,7 @@ Paint parseStroke( Paint parseFill( XmlElement el, Rect bounds, Map paintServers, {bool isShape = true}) { - final rawFill = _getAttribute(el, 'fill'); + final rawFill = getAttribute(el, 'fill'); if (rawFill == '') { if (isShape) { return new Paint() @@ -208,9 +202,9 @@ Paint parseFill( return paintServers[rawFill](bounds); } - var rawOpacity = _getAttribute(el, 'fill-opacity'); + var rawOpacity = getAttribute(el, 'fill-opacity'); if (rawOpacity == '') { - rawOpacity = _getAttribute(el, 'opacity'); + rawOpacity = getAttribute(el, 'opacity'); } final opacity = rawOpacity == '' ? rawFill == 'none' ? 0.0 : 1.0 @@ -222,3 +216,8 @@ Paint parseFill( ..color = fill ..style = PaintingStyle.fill; } + +PathFillType parseFillRule(XmlElement el) { + final String rawFillRule = getAttribute(el, 'fill-rule', 'nonzero'); + return rawFillRule == 'nonzero' ? PathFillType.nonZero : PathFillType.evenOdd; +} \ No newline at end of file diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 6bdf1c2bab27..fdc9e7692f35 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -30,8 +30,8 @@ final Map _shapes = { /// An SVG Shape element that will be drawn to the canvas. class DrawableSvgShape extends DrawableShape { - const DrawableSvgShape(Path path, Rect bounds, {Paint stroke, Paint fill}) - : super(path, bounds, stroke: stroke, fill: fill); + const DrawableSvgShape(Path path, {Paint stroke, Paint fill}) + : super(path, stroke: stroke, fill: fill); /// Applies the transformation in the @transform attribute to the path. static Path transformPath(Path path, XmlElement el) { @@ -47,12 +47,14 @@ class DrawableSvgShape extends DrawableShape { } } - static _createDrawable(Path path, Rect bounds, - Map paintServers, XmlElement el) { - final stroke = parseStroke(el, bounds, paintServers); - final fill = parseFill(el, bounds, paintServers); + static _createDrawable( + Path path, Map paintServers, XmlElement el) { + assert(path != null); + final stroke = parseStroke(el, path.getBounds(), paintServers); + final fill = parseFill(el, path.getBounds(), paintServers); + path.fillType = parseFillRule(el); - return new DrawableSvgShape(transformPath(path, el), bounds, + return new DrawableSvgShape(transformPath(path, el), stroke: stroke, fill: fill); } @@ -65,7 +67,7 @@ class DrawableSvgShape extends DrawableShape { final oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); final path = new Path()..addOval(oval); - return _createDrawable(path, oval, paintServers, el); + return _createDrawable(path, paintServers, el); } /// Creates a [DrawableSvgShape] from an SVG element. @@ -73,7 +75,7 @@ class DrawableSvgShape extends DrawableShape { XmlElement el, Map paintServers) { final d = el.getAttribute('d'); final Path path = parseSvgPathData(d); - return _createDrawable(path, path.getBounds(), paintServers, el); + return _createDrawable(path, paintServers, el); } /// Creates a [DrawableSvgShape] from an SVG element. @@ -95,14 +97,13 @@ class DrawableSvgShape extends DrawableShape { return _createDrawable( new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)), - rect, paintServers, el, ); } final path = new Path()..addRect(rect); - return _createDrawable(path, rect, paintServers, el); + return _createDrawable(path, paintServers, el); } /// Creates a [DrawableSvgShape] from an SVG or element. @@ -110,7 +111,7 @@ class DrawableSvgShape extends DrawableShape { XmlElement el, Map paintServers) { final path = parseSvgPathData('M' + el.getAttribute('points') + 'z'); - return _createDrawable(path, path.getBounds(), paintServers, el); + return _createDrawable(path, paintServers, el); } /// Creates a [DrawableSvgShape] from an SVG element. @@ -123,7 +124,7 @@ class DrawableSvgShape extends DrawableShape { Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); - return _createDrawable(new Path()..addOval(r), r, paintServers, el); + return _createDrawable(new Path()..addOval(r), paintServers, el); } /// Creates a [DrawableSvgShape] from an SVG element. @@ -137,7 +138,7 @@ class DrawableSvgShape extends DrawableShape { final path = new Path() ..moveTo(x1, x2) ..lineTo(y1, y2); - return _createDrawable(path, path.getBounds(), paintServers, el); + return _createDrawable(path, paintServers, el); } } diff --git a/third_party/lib/src/utilities/xml.dart b/third_party/lib/src/utilities/xml.dart new file mode 100644 index 000000000000..2ed59bdd22e0 --- /dev/null +++ b/third_party/lib/src/utilities/xml.dart @@ -0,0 +1,8 @@ +import 'package:xml/xml.dart'; + +/// Gets the attribute, trims it, and returns the attribute or default if the attribute +/// is null or ''. +String getAttribute(XmlElement el, String name, [String def = '', String namespace]) { + final String raw = el.getAttribute(name, namespace: namespace)?.trim(); + return raw == '' || raw == null ? def : raw; +} \ No newline at end of file diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index c43f2db2659b..38e4dab64e0b 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -13,9 +13,24 @@ abstract class Drawable { /// Draws the contents or children of this [Drawable] to the `canvas`, using /// the `parentPaint` to optionally override the child's paint. - void draw(Canvas canvas, [Paint parentPaint]); + void draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]); } +// class DrawableText implements Drawable { +// final String text; +// final TextStyle style; +// final Float64List transform; + +// const DrawableText(this.text, this.style, this.transform) +// : assert(text != null && text != ''); + +// @override +// bool get isVisible => true; + +// @override +// draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]) {} +// } + /// The root element of a drawable. class DrawableRoot implements Drawable { /// The expected coordinates used by child paths for drawing. @@ -61,7 +76,7 @@ class DrawableRoot implements Drawable { children.isNotEmpty == true && viewBox != null && !viewBox.isEmpty; @override - void draw(Canvas canvas, [Paint parentPaint]) { + void draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]) { children.forEach((child) => child.draw(canvas, parentPaint)); } } @@ -75,7 +90,7 @@ class DrawableNoop implements Drawable { bool get isVisible => false; @override - void draw(Canvas canvas, [Paint parentPaint]) {} + void draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]) {} } /// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. @@ -91,20 +106,20 @@ class DrawableGroup implements Drawable { bool get isVisible => children != null && children.length > 0; @override - void draw(Canvas canvas, [Paint parentPaint]) { + void draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]) { if (transform != null) { canvas.save(); canvas.transform(transform); } children.forEach((child) { if (stroke != null) { - child.draw(canvas, stroke); + child.draw(canvas, stroke, parentTextStyle); } if (fill != null) { - child.draw(canvas, fill); + child.draw(canvas, fill, parentTextStyle); } if (stroke == null && fill == null) { - child.draw(canvas); + child.draw(canvas, null, parentTextStyle); } }); if (transform != null) { @@ -118,17 +133,16 @@ class DrawableShape implements Drawable { final Paint stroke; final Paint fill; final Path path; - final Rect bounds; + Rect get bounds => path?.getBounds(); - const DrawableShape(this.path, this.bounds, {this.stroke, this.fill}) - : assert(path != null), - assert(bounds != null); + const DrawableShape(this.path, {this.stroke, this.fill}) + : assert(path != null); @override bool get isVisible => !bounds.isEmpty && (stroke != null || fill != null); @override - void draw(Canvas canvas, [Paint parentPaint]) { + void draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]) { if (parentPaint != null) { canvas.drawPath(path, parentPaint); return; diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 07f83452b5da..a29de681b919 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -7,55 +7,16 @@ import 'package:flutter/widgets.dart'; import 'package:xml/xml.dart' hide parse; import 'package:xml/xml.dart' as xml show parse; +import 'vector_drawable.dart'; import 'src/vector_painter.dart'; import 'src/svg_parser.dart'; import 'src/svg/xml_parsers.dart'; -enum PaintLocation { Foreground, Background } - -/// Handles rendering [Drawables] to a canvas. -class VectorDrawableImage extends StatelessWidget { - final Size size; - final Future future; - final bool clipToViewBox; - final PaintLocation paintLocation; - - const VectorDrawableImage._(this.future, this.size, - {this.clipToViewBox = true, - Key key, - this.paintLocation = PaintLocation.Background}) - : super(key: key); - - Widget build(BuildContext context) { - return new FutureBuilder( - future: future, - builder: ((context, snapShot) { - if (snapShot.hasData) { - final CustomPainter painter = - new VectorPainter(snapShot.data, clipToViewBox: clipToViewBox); - return new RepaintBoundary.wrap( - CustomPaint( - painter: - paintLocation == PaintLocation.Background ? painter : null, - foregroundPainter: - paintLocation == PaintLocation.Foreground ? painter : null, - size: size, - isComplex: true, - willChange: false, - ), - 0); - } - return new LimitedBox(); - }), - ); - } -} - /// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. class SvgImage extends VectorDrawableImage { SvgImage._(Future future, Size size, {bool clipToViewBox, Key key, PaintLocation paintLocation}) - : super._(future, size, + : super(future, size, clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation); diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart new file mode 100644 index 000000000000..139174626743 --- /dev/null +++ b/third_party/lib/vector_drawable.dart @@ -0,0 +1,46 @@ +import 'dart:async'; +import 'dart:ui'; + +import 'package:flutter/widgets.dart'; + +import 'src/vector_painter.dart'; + +enum PaintLocation { Foreground, Background } + +/// Handles rendering [Drawables] to a canvas. +class VectorDrawableImage extends StatelessWidget { + final Size size; + final Future future; + final bool clipToViewBox; + final PaintLocation paintLocation; + + const VectorDrawableImage(this.future, this.size, + {this.clipToViewBox = true, + Key key, + this.paintLocation = PaintLocation.Background}) + : super(key: key); + + Widget build(BuildContext context) { + return new FutureBuilder( + future: future, + builder: ((context, snapShot) { + if (snapShot.hasData) { + final CustomPainter painter = + new VectorPainter(snapShot.data, clipToViewBox: clipToViewBox); + return new RepaintBoundary.wrap( + CustomPaint( + painter: + paintLocation == PaintLocation.Background ? painter : null, + foregroundPainter: + paintLocation == PaintLocation.Foreground ? painter : null, + size: size, + isComplex: true, + willChange: false, + ), + 0); + } + return new LimitedBox(); + }), + ); + } +} diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 73801f2bfd8a..6a8f5596b98d 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -50,6 +50,7 @@ flutter: - assets/simple/linear_gradient_2.svg - assets/simple/radial_gradient.svg - assets/wikimedia/Ghostscript_Tiger.svg + - assets/android_vd/battery_charging.xml # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg From caf5602a8f2cbe46c713666334e20a5fff01644f Mon Sep 17 00:00:00 2001 From: Fabio de Matos Date: Tue, 1 May 2018 11:30:51 +1000 Subject: [PATCH 035/512] Fix error on slider value > max, update flutter min version --- third_party/lib/main.dart | 4 ++++ third_party/pubspec.lock | 2 +- third_party/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index a8b1eb90263e..0a1fa3afbb60 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -88,6 +88,10 @@ class _MyHomePageState extends State { @override Widget build(BuildContext context) { + + if ( _dimension > MediaQuery.of(context).size.width - 10.0){ + _dimension = MediaQuery.of(context).size.width - 10.0; + } return new Scaffold( appBar: new AppBar( title: new Text(widget.title), diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 887be0e48793..dd6535febc1d 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -410,4 +410,4 @@ packages: version: "2.1.13" sdks: dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.0d5cf900b021bf5c9fa593ffa12b15bcd1cc5fe0" - flutter: ">=0.3.5 <2.0.0" + flutter: ">=0.3.6-pre.65 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 6a8f5596b98d..75a5f8bc4589 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -81,4 +81,4 @@ flutter: # see https://flutter.io/custom-fonts/#from-packages environment: - flutter: ">=0.3.5 <2.0.0" + flutter: ">=0.3.6-pre.65 <2.0.0" From b8b16653e1dc114c9dfd1f5219be3562d42b7eea Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 1 May 2018 14:24:04 -0400 Subject: [PATCH 036/512] inheritance improvements --- third_party/assets/simple/rect_rrect.svg | 4 +- third_party/lib/avd.dart | 1 - third_party/lib/main.dart | 2 +- third_party/lib/src/avd/xml_parsers.dart | 1 - third_party/lib/src/avd_parser.dart | 20 +++-- third_party/lib/src/svg/xml_parsers.dart | 13 +-- third_party/lib/src/svg_parser.dart | 17 ++-- third_party/lib/src/vector_painter.dart | 108 ++++++++++++++--------- 8 files changed, 95 insertions(+), 71 deletions(-) diff --git a/third_party/assets/simple/rect_rrect.svg b/third_party/assets/simple/rect_rrect.svg index b1b5eb015da8..fea9e855cfb5 100644 --- a/third_party/assets/simple/rect_rrect.svg +++ b/third_party/assets/simple/rect_rrect.svg @@ -1,4 +1,6 @@ - + + + diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index ef873fcda10e..70531f2471e1 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -110,7 +110,6 @@ Future _consolidateHttpClientResponse( buffer.write(chunk); }, onDone: () { // There's a bug right now where sometimes GZIP encoded payloads aren't coming all the way through.. - print(buffer.toString()); completer.complete(buffer.toString()); }, onError: completer.completeError, cancelOnError: true); diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 0a1fa3afbb60..f928a429a3f9 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -28,7 +28,7 @@ const List assetNames = const [ const List uriNames = const [ // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg' + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', ]; void main() => runApp(new MyApp()); diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index 43fcec1898b2..cb45f2cd239a 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -32,7 +32,6 @@ Matrix4 parseTransform(XmlElement el) { double translateY = double.parse(getAttribute(el, 'translateY', '0', androidNS)); - print('$pivotX $pivotY'); return new Matrix4.identity() ..translate(pivotX, pivotY) ..rotateZ(rotation * pi / 180) diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index 282006331e00..5de92fc96f66 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -8,15 +8,14 @@ import 'vector_painter.dart'; import 'avd/xml_parsers.dart'; class DrawableAvdRoot extends DrawableRoot { - const DrawableAvdRoot( - Rect viewBox, List children, Map paintServers) + const DrawableAvdRoot(Rect viewBox, List children, + Map paintServers) : super(viewBox, children, paintServers); } /// An SVG Shape element that will be drawn to the canvas. class DrawableAvdPath extends DrawableShape { - const DrawableAvdPath(Path path, {Paint stroke, Paint fill}) - : super(path, stroke: stroke, fill: fill); + const DrawableAvdPath(Path path, DrawableStyle style) : super(path, style); /// Creates a [DrawableAvdPath] from an XML element factory DrawableAvdPath.fromXml(XmlElement el) { @@ -28,7 +27,10 @@ class DrawableAvdPath extends DrawableShape { final stroke = parseStroke(el, path.getBounds()); final fill = parseFill(el, path.getBounds()); - return new DrawableAvdPath(path, stroke: stroke, fill: fill); + return new DrawableAvdPath( + path, + new DrawableStyle(stroke: stroke, fill: fill), + ); } } @@ -65,8 +67,10 @@ Drawable parseAvdGroup(XmlElement el, Rect bounds) { return new DrawableGroup( children, - transform?.storage, - stroke, - fill, + new DrawableStyle( + transform: transform?.storage, + stroke: stroke, + fill: fill, + ), ); } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index e41d09d4fe3f..afbda1198929 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -185,17 +185,10 @@ Paint parseStroke( } Paint parseFill( - XmlElement el, Rect bounds, Map paintServers, - {bool isShape = true}) { + XmlElement el, Rect bounds, Map paintServers) { final rawFill = getAttribute(el, 'fill'); if (rawFill == '') { - if (isShape) { - return new Paint() - ..color = colorBlack - ..style = PaintingStyle.fill; - } else { - return null; - } + return null; } if (rawFill.startsWith('url')) { @@ -220,4 +213,4 @@ Paint parseFill( PathFillType parseFillRule(XmlElement el) { final String rawFillRule = getAttribute(el, 'fill-rule', 'nonzero'); return rawFillRule == 'nonzero' ? PathFillType.nonZero : PathFillType.evenOdd; -} \ No newline at end of file +} diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index fdc9e7692f35..ab86e9314b85 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -30,8 +30,7 @@ final Map _shapes = { /// An SVG Shape element that will be drawn to the canvas. class DrawableSvgShape extends DrawableShape { - const DrawableSvgShape(Path path, {Paint stroke, Paint fill}) - : super(path, stroke: stroke, fill: fill); + const DrawableSvgShape(Path path, DrawableStyle style) : super(path, style); /// Applies the transformation in the @transform attribute to the path. static Path transformPath(Path path, XmlElement el) { @@ -54,8 +53,10 @@ class DrawableSvgShape extends DrawableShape { final fill = parseFill(el, path.getBounds(), paintServers); path.fillType = parseFillRule(el); - return new DrawableSvgShape(transformPath(path, el), - stroke: stroke, fill: fill); + return new DrawableSvgShape( + transformPath(path, el), + new DrawableStyle(fill: fill, stroke: stroke), + ); } /// Creates a [DrawableSvgShape] from an SVG element. @@ -177,7 +178,7 @@ Drawable parseSvgGroup( }); final Matrix4 transform = parseTransform(el.getAttribute('transform')); - final Paint fill = parseFill(el, bounds, paintServers, isShape: false); + final Paint fill = parseFill(el, bounds, paintServers); final Paint stroke = parseStroke(el, bounds, paintServers); return new DrawableGroup( @@ -186,6 +187,10 @@ Drawable parseSvgGroup( // el.children // .whereType() // .map((child) => new SvgBaseElement.fromXml(child)), - transform?.storage, stroke, fill, + new DrawableStyle( + transform: transform?.storage, + stroke: stroke, + fill: fill, + ), ); } diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 38e4dab64e0b..e7168237aea4 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -13,23 +13,47 @@ abstract class Drawable { /// Draws the contents or children of this [Drawable] to the `canvas`, using /// the `parentPaint` to optionally override the child's paint. - void draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]); + void draw(Canvas canvas, [DrawableStyle parentStyle]); } -// class DrawableText implements Drawable { -// final String text; -// final TextStyle style; -// final Float64List transform; +@immutable +class DrawableStyle { + final Paint stroke; + final Paint fill; + final Float64List transform; + final TextStyle textStyle; + + const DrawableStyle({this.stroke, this.fill, this.transform, this.textStyle}); + + /// Creates a new [DrawableStyle] if `other` is not null, filling in any null properties on + /// this with the properties from other. + /// + /// If `other` is null, returns this. + DrawableStyle merge(DrawableStyle other) { + if (other == null) return this; + + return new DrawableStyle( + fill: this.fill ?? other.fill, + stroke: this.stroke ?? other.stroke, + transform: this.transform ?? other.transform, + textStyle: this.textStyle ?? other.textStyle); + } +} -// const DrawableText(this.text, this.style, this.transform) -// : assert(text != null && text != ''); +class DrawableText implements Drawable { + final String text; + final TextStyle style; + final Float64List transform; -// @override -// bool get isVisible => true; + const DrawableText(this.text, this.style, this.transform) + : assert(text != null && text != ''); -// @override -// draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]) {} -// } + @override + bool get isVisible => true; + + @override + draw(Canvas canvas, [DrawableStyle parentStyle]) {} +} /// The root element of a drawable. class DrawableRoot implements Drawable { @@ -76,8 +100,8 @@ class DrawableRoot implements Drawable { children.isNotEmpty == true && viewBox != null && !viewBox.isEmpty; @override - void draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]) { - children.forEach((child) => child.draw(canvas, parentPaint)); + void draw(Canvas canvas, [DrawableStyle parentStyle]) { + children.forEach((child) => child.draw(canvas, parentStyle)); } } @@ -90,39 +114,29 @@ class DrawableNoop implements Drawable { bool get isVisible => false; @override - void draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]) {} + void draw(Canvas canvas, [DrawableStyle parentStyle]) {} } /// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. class DrawableGroup implements Drawable { final List children; - final Paint stroke; - final Paint fill; - final Float64List transform; + final DrawableStyle style; - const DrawableGroup(this.children, this.transform, this.stroke, this.fill); + const DrawableGroup(this.children, this.style); @override bool get isVisible => children != null && children.length > 0; @override - void draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]) { - if (transform != null) { + void draw(Canvas canvas, [DrawableStyle parentStyle]) { + if (style?.transform != null) { canvas.save(); - canvas.transform(transform); + canvas.transform(style?.transform); } children.forEach((child) { - if (stroke != null) { - child.draw(canvas, stroke, parentTextStyle); - } - if (fill != null) { - child.draw(canvas, fill, parentTextStyle); - } - if (stroke == null && fill == null) { - child.draw(canvas, null, parentTextStyle); - } + child.draw(canvas, style?.merge(parentStyle) ?? parentStyle); }); - if (transform != null) { + if (style?.transform != null) { canvas.restore(); } } @@ -130,25 +144,33 @@ class DrawableGroup implements Drawable { /// Represents a drawing element that will be rendered to the canvas. class DrawableShape implements Drawable { - final Paint stroke; - final Paint fill; + final DrawableStyle style; final Path path; + static final Paint _blackPaint = new Paint()..color = const Color(0xFF000000); + Rect get bounds => path?.getBounds(); - const DrawableShape(this.path, {this.stroke, this.fill}) - : assert(path != null); + const DrawableShape(this.path, this.style) : assert(path != null); @override - bool get isVisible => !bounds.isEmpty && (stroke != null || fill != null); + bool get isVisible => + !bounds.isEmpty && (style?.stroke != null || style?.fill != null); @override - void draw(Canvas canvas, [Paint parentPaint, TextStyle parentTextStyle]) { - if (parentPaint != null) { - canvas.drawPath(path, parentPaint); - return; + void draw(Canvas canvas, [DrawableStyle parentStyle]) { + if (style?.stroke != null) { + canvas.drawPath(path, style.stroke); + } else if (parentStyle?.stroke != null) { + canvas.drawPath(path, parentStyle.stroke); + } + + if (style?.fill != null) { + canvas.drawPath(path, style.fill); + } else if (parentStyle?.fill != null) { + canvas.drawPath(path, parentStyle.fill); + } else { + canvas.drawPath(path, _blackPaint); } - if (stroke != null) canvas.drawPath(path, stroke); - if (fill != null) canvas.drawPath(path, fill); } } From 9756650d5fc7df16f2a78d4bd223515dc88d4d4d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 1 May 2018 14:32:45 -0400 Subject: [PATCH 037/512] update pubspec --- third_party/pubspec.lock | 6 +++--- third_party/pubspec.yaml | 12 +++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index dd6535febc1d..2f83234a6652 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -180,7 +180,7 @@ packages: source: hosted version: "0.12.1+4" meta: - dependency: transitive + dependency: "direct main" description: name: meta url: "https://pub.dartlang.org" @@ -353,7 +353,7 @@ packages: source: hosted version: "1.0.0" test: - dependency: transitive + dependency: "direct dev" description: name: test url: "https://pub.dartlang.org" @@ -410,4 +410,4 @@ packages: version: "2.1.13" sdks: dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.0d5cf900b021bf5c9fa593ffa12b15bcd1cc5fe0" - flutter: ">=0.3.6-pre.65 <2.0.0" + flutter: ">=0.3.6-pre.53 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 75a5f8bc4589..6f80e98cbaf9 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,10 +1,14 @@ name: flutter_svg -description: A new Flutter project. +description: An SVG rendering and widget library for Flutter. +author: Dan Field +homepage: https://github.com/dnfield/flutter_svg +version: 0.0.1 dependencies: path_drawing: ^0.1.1 xml: ^3.0.0 - vector_math: any + vector_math: ^2.0.4 + meta: ^1.1.2 flutter: sdk: flutter @@ -13,6 +17,7 @@ dependencies: cupertino_icons: ^0.1.0 dev_dependencies: + test: ^0.12.34 flutter_test: sdk: flutter @@ -81,4 +86,5 @@ flutter: # see https://flutter.io/custom-fonts/#from-packages environment: - flutter: ">=0.3.6-pre.65 <2.0.0" + sdk: ">=1.19.0" + flutter: ">=0.3.6-pre.53 <2.0.0" From 63b5a37593c6da9c6145218d30f46828615e5773 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 6 May 2018 19:04:49 -0400 Subject: [PATCH 038/512] initial text support, treat as , flutter version fix --- third_party/assets/simple/text.svg | 16 +++++ third_party/lib/main.dart | 3 +- third_party/lib/src/avd_parser.dart | 3 +- third_party/lib/src/svg/parsers.dart | 2 +- third_party/lib/src/svg/xml_parsers.dart | 2 +- third_party/lib/src/svg_parser.dart | 81 +++++++++++++++++------- third_party/lib/src/vector_painter.dart | 32 +++++++--- third_party/lib/svg.dart | 2 - third_party/pubspec.lock | 4 +- third_party/pubspec.yaml | 31 +-------- 10 files changed, 105 insertions(+), 71 deletions(-) create mode 100644 third_party/assets/simple/text.svg diff --git a/third_party/assets/simple/text.svg b/third_party/assets/simple/text.svg new file mode 100644 index 000000000000..ac5bb68b079a --- /dev/null +++ b/third_party/assets/simple/text.svg @@ -0,0 +1,16 @@ + + + + Example text01 - 'Hello, out there' in blue + + + Hello, out there + + + + + \ No newline at end of file diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index f928a429a3f9..56c6b73bb83b 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -5,6 +5,7 @@ import 'package:flutter_svg/svg.dart'; const List assetNames = const [ 'assets/flutter_logo.svg', + 'assets/simple/text.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', 'assets/simple/radial_gradient.svg', @@ -27,7 +28,7 @@ const List assetNames = const [ ]; const List uriNames = const [ - // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', ]; diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index 5de92fc96f66..b51124b3a0b5 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -6,6 +6,7 @@ import 'package:vector_math/vector_math_64.dart'; import 'vector_painter.dart'; import 'avd/xml_parsers.dart'; +import 'utilities/xml.dart'; class DrawableAvdRoot extends DrawableRoot { const DrawableAvdRoot(Rect viewBox, List children, @@ -19,7 +20,7 @@ class DrawableAvdPath extends DrawableShape { /// Creates a [DrawableAvdPath] from an XML element factory DrawableAvdPath.fromXml(XmlElement el) { - final d = el.getAttribute('pathData', namespace: androidNS); + final d = getAttribute(el, 'pathData', '', androidNS); final Path path = parseSvgPathData(d); assert(path != null); diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index db173c214f3a..5e21a80f7c3c 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -22,7 +22,7 @@ const Map _matrixParsers = const { /// Based on work in the "vi-tool" by @amirh, but extended to support additional /// transforms and use a Matrix4 rather than Matrix3 for the affine matrices. Matrix4 parseTransform(String transform) { - if (transform == null) { + if (transform == null || transform == '') { return null; } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index afbda1198929..451b0db7905b 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -41,7 +41,7 @@ void parseDefs(XmlElement el, Map paintServers) { el.children.forEach((XmlNode def) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { - paintServers['url(#${def.getAttribute('id')})'] = + paintServers['url(#${getAttribute(def, 'id')})'] = (Rect bounds) => parseGradient(def, bounds); } } diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index ab86e9314b85..1323842e53d4 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -5,8 +5,10 @@ import 'package:path_drawing/path_drawing.dart'; import 'package:vector_math/vector_math_64.dart'; import 'vector_painter.dart'; +import 'svg/colors.dart'; import 'svg/parsers.dart'; import 'svg/xml_parsers.dart'; +import 'utilities/xml.dart'; typedef DrawableSvgShape SvgShapeFactory( XmlElement el, Map paintServers); @@ -37,7 +39,8 @@ class DrawableSvgShape extends DrawableShape { assert(path != null); assert(el != null); - final Matrix4 transform = parseTransform(el.getAttribute('transform')); + final Matrix4 transform = + parseTransform(getAttribute(el, 'transform', null)); if (transform != null) { return path.transform(transform.storage); @@ -62,9 +65,9 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgCircle( XmlElement el, Map paintServers) { - final cx = double.parse(el.getAttribute('cx')); - final cy = double.parse(el.getAttribute('cy')); - final r = double.parse(el.getAttribute('r')); + final cx = double.parse(getAttribute(el, 'cx', '0')); + final cy = double.parse(getAttribute(el, 'cy', '0')); + final r = double.parse(getAttribute(el, 'r', '0')); final oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); final path = new Path()..addOval(oval); @@ -74,7 +77,7 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgPath( XmlElement el, Map paintServers) { - final d = el.getAttribute('d'); + final d = getAttribute(el, 'd'); final Path path = parseSvgPathData(d); return _createDrawable(path, paintServers, el); } @@ -82,13 +85,13 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgRect( XmlElement el, Map paintServers) { - final double x = double.parse(el.getAttribute('x')); - final double y = double.parse(el.getAttribute('y')); - final double w = double.parse(el.getAttribute('width')); - final double h = double.parse(el.getAttribute('height')); + final double x = double.parse(getAttribute(el, 'x', '0')); + final double y = double.parse(getAttribute(el, 'y', '0')); + final double w = double.parse(getAttribute(el, 'width', '0')); + final double h = double.parse(getAttribute(el, 'height', '0')); final Rect rect = new Rect.fromLTWH(x, y, w, h); - String rxRaw = el.getAttribute('rx'); - String ryRaw = el.getAttribute('ry'); + String rxRaw = getAttribute(el, 'rx', '0'); + String ryRaw = getAttribute(el, 'ry', '0'); rxRaw ??= ryRaw; ryRaw ??= rxRaw; @@ -110,7 +113,11 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG or element. factory DrawableSvgShape.fromSvgPolygonOrLine( XmlElement el, Map paintServers) { - final path = parseSvgPathData('M' + el.getAttribute('points') + 'z'); + final points = getAttribute(el, 'points'); + if (points == '') { + return _createDrawable(null, paintServers, el); + } + final path = parseSvgPathData('M' + points + 'z'); return _createDrawable(path, paintServers, el); } @@ -118,10 +125,10 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgEllipse( XmlElement el, Map paintServers) { - final cx = double.parse(el.getAttribute('cx')); - final cy = double.parse(el.getAttribute('cy')); - final rx = double.parse(el.getAttribute('rx')); - final ry = double.parse(el.getAttribute('ry')); + final cx = double.parse(getAttribute(el, 'cx', '0')); + final cy = double.parse(getAttribute(el, 'cy', '0')); + final rx = double.parse(getAttribute(el, 'rx', '0')); + final ry = double.parse(getAttribute(el, 'ry', '0')); Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); @@ -131,10 +138,10 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgLine( XmlElement el, Map paintServers) { - final x1 = double.parse(el.getAttribute('x1')); - final x2 = double.parse(el.getAttribute('x2')); - final y1 = double.parse(el.getAttribute('y1')); - final y2 = double.parse(el.getAttribute('y2')); + final x1 = double.parse(getAttribute(el, 'x1', '0')); + final x2 = double.parse(getAttribute(el, 'x2', '0')); + final y1 = double.parse(getAttribute(el, 'y1', '0')); + final y2 = double.parse(getAttribute(el, 'y2', '0')); final path = new Path() ..moveTo(x1, x2) @@ -153,10 +160,11 @@ Drawable parseSvgElement( return shapeFn(el, paintServers); } else if (el.name.local == 'defs') { parseDefs(el, paintServers); - } else if (el.name.local == 'g') { + } else if (el.name.local == 'g' || el.name.local == 'a') { return parseSvgGroup(el, paintServers, bounds); - } - if (el.name.local == 'svg') { + } else if (el.name.local == 'text') { + return parseSvgText(el, paintServers, bounds); + } else if (el.name.local == 'svg') { throw new UnsupportedError( 'Nested SVGs not supported in this implementation.'); } @@ -164,6 +172,31 @@ Drawable parseSvgElement( return new DrawableNoop(el.name.local); } +Drawable parseSvgText( + XmlElement el, Map paintServers, Rect bounds) { + final Offset offset = new Offset(double.parse(getAttribute(el, 'x', '0')), + double.parse(getAttribute(el, 'y', '0'))); + return new DrawableText( + el.text, + offset, + new DrawableStyle( + stroke: new Paint()..color = const Color(0xFFABABAB), + textStyle: new TextStyle( + fontFamily: getAttribute(el, 'font-family'), + fontSize: double.parse(getAttribute(el, 'font-size', '55')), + color: parseColor( + getAttribute( + el, + 'fill', + getAttribute(el, 'stroke', 'black'), + ), + ), + height: -1.0, + ), + ), + ); +} + /// Parses an SVG element. Drawable parseSvgGroup( XmlElement el, Map paintServers, Rect bounds) { @@ -177,7 +210,7 @@ Drawable parseSvgGroup( } }); - final Matrix4 transform = parseTransform(el.getAttribute('transform')); + final Matrix4 transform = parseTransform(getAttribute(el, 'transform')); final Paint fill = parseFill(el, bounds, paintServers); final Paint stroke = parseStroke(el, bounds, paintServers); diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index e7168237aea4..4f84bd73c251 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -1,6 +1,7 @@ import 'dart:typed_data'; +import 'dart:ui'; -import 'package:flutter/widgets.dart'; +import 'package:flutter/widgets.dart' hide TextStyle; import 'package:meta/meta.dart'; typedef Paint PaintServer(Rect bounds); @@ -41,18 +42,29 @@ class DrawableStyle { } class DrawableText implements Drawable { - final String text; - final TextStyle style; - final Float64List transform; + final Offset offset; + final DrawableStyle style; + final Paragraph _paragraph; - const DrawableText(this.text, this.style, this.transform) - : assert(text != null && text != ''); + DrawableText(text, this.offset, this.style) + : assert(text != null && text != ''), + _paragraph = _buildParagraph(text, style); + + static Paragraph _buildParagraph(String text, DrawableStyle style) { + final ParagraphBuilder pb = new ParagraphBuilder(new ParagraphStyle()) + ..pushStyle(style.textStyle) + ..addText(text); + + return pb.build()..layout(new ParagraphConstraints(width: double.infinity)); + } @override - bool get isVisible => true; + bool get isVisible => _paragraph.width > 0.0; @override - draw(Canvas canvas, [DrawableStyle parentStyle]) {} + draw(Canvas canvas, [DrawableStyle parentStyle]) { + canvas.drawParagraph(_paragraph, offset); + } } /// The root element of a drawable. @@ -146,7 +158,7 @@ class DrawableGroup implements Drawable { class DrawableShape implements Drawable { final DrawableStyle style; final Path path; - static final Paint _blackPaint = new Paint()..color = const Color(0xFF000000); + static final Paint _blackPaint = new Paint()..color = const Color(0xFF000000); Rect get bounds => path?.getBounds(); @@ -163,7 +175,7 @@ class DrawableShape implements Drawable { } else if (parentStyle?.stroke != null) { canvas.drawPath(path, parentStyle.stroke); } - + if (style?.fill != null) { canvas.drawPath(path, style.fill); } else if (parentStyle?.fill != null) { diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index a29de681b919..7c38695bb425 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -111,8 +111,6 @@ Future _consolidateHttpClientResponse( response.transform(utf8.decoder).listen((String chunk) { buffer.write(chunk); }, onDone: () { - // There's a bug right now where sometimes GZIP encoded payloads aren't coming all the way through.. - print(buffer.toString()); completer.complete(buffer.toString()); }, onError: completer.completeError, cancelOnError: true); diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 2f83234a6652..b2801aba70e8 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -409,5 +409,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.0d5cf900b021bf5c9fa593ffa12b15bcd1cc5fe0" - flutter: ">=0.3.6-pre.53 <2.0.0" + dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.c080951d45e79cd25df98036c4be835b284a269c" + flutter: ">=0.3.6 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 6f80e98cbaf9..5e61d68c8d96 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -54,37 +54,10 @@ flutter: - assets/simple/linear_gradient.svg - assets/simple/linear_gradient_2.svg - assets/simple/radial_gradient.svg + - assets/simple/text.svg - assets/wikimedia/Ghostscript_Tiger.svg - assets/android_vd/battery_charging.xml - # - images/a_dot_burr.jpeg - # - images/a_dot_ham.jpeg - - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.io/assets-and-images/#resolution-aware. - - # For details regarding adding assets from package dependencies, see - # https://flutter.io/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: - # fonts: - # - family: Schyler - # fonts: - # - asset: fonts/Schyler-Regular.ttf - # - asset: fonts/Schyler-Italic.ttf - # style: italic - # - family: Trajan Pro - # fonts: - # - asset: fonts/TrajanPro.ttf - # - asset: fonts/TrajanPro_Bold.ttf - # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.io/custom-fonts/#from-packages environment: sdk: ">=1.19.0" - flutter: ">=0.3.6-pre.53 <2.0.0" + flutter: ">=0.3.6 <2.0.0" From eacafd1095e1196758a152369730b5bb09743744 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 6 May 2018 19:10:24 -0400 Subject: [PATCH 039/512] remove network test --- third_party/pubspec.yaml | 2 +- third_party/test/network_test.dart | 74 ------------------------------ 2 files changed, 1 insertion(+), 75 deletions(-) delete mode 100644 third_party/test/network_test.dart diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 5e61d68c8d96..9c96b8fddac3 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.0.1 +version: 0.0.2 dependencies: path_drawing: ^0.1.1 diff --git a/third_party/test/network_test.dart b/third_party/test/network_test.dart deleted file mode 100644 index 891b3e5f7937..000000000000 --- a/third_party/test/network_test.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'dart:convert'; - -import 'package:flutter/services.dart'; -import 'package:test/test.dart'; - -void main() { - test('GZIP', () async { - String svg = await loadNetworkAsset2( - 'https://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg'); - expect(svg, ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'''); - }); -} - -Future loadNetworkAsset(String uri) async { - final NetworkAssetBundle _network = - new NetworkAssetBundle(Uri.base.resolve(uri)); - return await _network.loadString(uri); -} - -Future loadNetworkAsset2(String url) async { - final HttpClientRequest request = - await new HttpClient().getUrl(Uri.base.resolve(url)); - final HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.OK) throw new Error(); - return await consolidateHttpClientResponse(response); -} - -Future consolidateHttpClientResponse( - HttpClientResponse response) async { - final Completer completer = new Completer.sync(); - final StringBuffer buffer = new StringBuffer(); - - response.transform(utf8.decoder).listen((String chunk) { - buffer.write(chunk); - }, onDone: () { - completer.complete(buffer.toString()); - }, onError: completer.completeError, cancelOnError: true); - - return completer.future; -} From a961ced286581cdb6e640e867c600ecbff8cb36c Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 6 May 2018 19:11:48 -0400 Subject: [PATCH 040/512] add changelog --- third_party/CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 third_party/CHANGELOG.md diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md new file mode 100644 index 000000000000..0fa8f03e2118 --- /dev/null +++ b/third_party/CHANGELOG.md @@ -0,0 +1,9 @@ +# CHANGES + +## 0.0.1 + +Initial release. Relies on pre-released master + +## 0.0.2 + +Initial text support. Relies on flutter 0.3.6 \ No newline at end of file From a731b17a262d58c7c2aeb56071cb34e8971f5698 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 8 May 2018 23:02:16 -0400 Subject: [PATCH 041/512] initial dash path support; fix bug with line --- third_party/assets/simple/dash_path.svg | 14 +++++++++ third_party/lib/main.dart | 1 + third_party/lib/src/svg/xml_parsers.dart | 38 ++++++++++++++++++++---- third_party/lib/src/svg_parser.dart | 14 ++++++--- third_party/lib/src/vector_painter.dart | 35 ++++++++++++++++------ third_party/pubspec.lock | 4 +-- third_party/pubspec.yaml | 5 ++-- 7 files changed, 88 insertions(+), 23 deletions(-) create mode 100644 third_party/assets/simple/dash_path.svg diff --git a/third_party/assets/simple/dash_path.svg b/third_party/assets/simple/dash_path.svg new file mode 100644 index 000000000000..cbd5fa9a4b85 --- /dev/null +++ b/third_party/assets/simple/dash_path.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index 56c6b73bb83b..e9bffba73a8a 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -23,6 +23,7 @@ const List assetNames = const [ 'assets/deborah_ufw/new-send-circle.svg', 'assets/deborah_ufw/numeric_25.svg', 'assets/simple/ellipse.svg', + 'assets/simple/dash_path.svg', 'assets/simple/nested_group.svg', 'assets/wikimedia/Ghostscript_Tiger.svg', ]; diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 451b0db7905b..985e0095109e 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +import 'package:path_drawing/path_drawing.dart'; import 'package:xml/xml.dart'; import '../vector_painter.dart'; @@ -133,6 +134,37 @@ Paint parseGradient(XmlElement el, Rect bounds) { throw new StateError('Unknown gradient type ${el.name.local}'); } +/// Parses an @stroke-dasharray attribute into a [CircularIntervalList] +/// +/// Does not currently support percentages. +CircularIntervalList parseDashArray(XmlElement el) { + final String rawDashArray = getAttribute(el, 'stroke-dasharray'); + if (rawDashArray == '') { + return null; + } + + final List parts = rawDashArray.split(new RegExp(r'[ ,]+')); + return new CircularIntervalList( + parts.map((part) => double.parse(part)).toList()); +} + +/// Parses a @stroke-dashoffset into a [DashOffset] +DashOffset parseDashOffset(XmlElement el) { + String rawDashOffset = getAttribute(el, 'stroke-dashoffset'); + if (rawDashOffset == '') { + return null; + } + + if (rawDashOffset.endsWith('%')) { + final double percentage = + double.parse(rawDashOffset.substring(0, rawDashOffset.length - 1)) / + 100; + return new DashOffset.percentage(percentage); + } else { + return new DashOffset.absolute(double.parse(rawDashOffset)); + } +} + /// Parses a @stroke attribute into a [Paint]. Paint parseStroke( XmlElement el, Rect bounds, Map paintServers) { @@ -175,12 +207,6 @@ Paint parseStroke( final String rawStrokeWidth = getAttribute(el, 'stroke-width'); paint.strokeWidth = rawStrokeWidth == '' ? 1.0 : double.parse(rawStrokeWidth); - // TODO: Dash patterns not currently supported - if (getAttribute(el, 'stroke-dashoffset') != '' || - getAttribute(el, 'stroke-dasharray') != '') { - print('Warning: Dash patterns not currently supported'); - } - return paint; } diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 1323842e53d4..1f453eef07bb 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -58,7 +58,12 @@ class DrawableSvgShape extends DrawableShape { return new DrawableSvgShape( transformPath(path, el), - new DrawableStyle(fill: fill, stroke: stroke), + new DrawableStyle( + fill: fill, + stroke: stroke, + dashArray: parseDashArray(el), + dashOffset: parseDashOffset(el), + ), ); } @@ -144,8 +149,8 @@ class DrawableSvgShape extends DrawableShape { final y2 = double.parse(getAttribute(el, 'y2', '0')); final path = new Path() - ..moveTo(x1, x2) - ..lineTo(y1, y2); + ..moveTo(x1, y1) + ..lineTo(x2, y2); return _createDrawable(path, paintServers, el); } } @@ -180,7 +185,6 @@ Drawable parseSvgText( el.text, offset, new DrawableStyle( - stroke: new Paint()..color = const Color(0xFFABABAB), textStyle: new TextStyle( fontFamily: getAttribute(el, 'font-family'), fontSize: double.parse(getAttribute(el, 'font-size', '55')), @@ -223,6 +227,8 @@ Drawable parseSvgGroup( new DrawableStyle( transform: transform?.storage, stroke: stroke, + dashArray: parseDashArray(el), + dashOffset: parseDashOffset(el), fill: fill, ), ); diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 4f84bd73c251..2e7d378ef5c0 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -1,6 +1,7 @@ import 'dart:typed_data'; import 'dart:ui'; +import 'package:path_drawing/path_drawing.dart'; import 'package:flutter/widgets.dart' hide TextStyle; import 'package:meta/meta.dart'; @@ -20,11 +21,19 @@ abstract class Drawable { @immutable class DrawableStyle { final Paint stroke; + final CircularIntervalList dashArray; + final DashOffset dashOffset; final Paint fill; final Float64List transform; final TextStyle textStyle; - const DrawableStyle({this.stroke, this.fill, this.transform, this.textStyle}); + const DrawableStyle( + {this.stroke, + this.dashArray, + this.dashOffset, + this.fill, + this.transform, + this.textStyle}); /// Creates a new [DrawableStyle] if `other` is not null, filling in any null properties on /// this with the properties from other. @@ -36,6 +45,8 @@ class DrawableStyle { return new DrawableStyle( fill: this.fill ?? other.fill, stroke: this.stroke ?? other.stroke, + dashArray: this.dashArray ?? other.dashArray, + dashOffset: this.dashOffset ?? other.dashOffset, transform: this.transform ?? other.transform, textStyle: this.textStyle ?? other.textStyle); } @@ -170,16 +181,22 @@ class DrawableShape implements Drawable { @override void draw(Canvas canvas, [DrawableStyle parentStyle]) { - if (style?.stroke != null) { - canvas.drawPath(path, style.stroke); - } else if (parentStyle?.stroke != null) { - canvas.drawPath(path, parentStyle.stroke); + final DrawableStyle localStyle = style.merge(parentStyle); + + if (localStyle?.stroke != null) { + if (localStyle.dashArray != null) { + canvas.drawPath( + dashPath(path, + dashArray: localStyle.dashArray, + dashOffset: localStyle.dashOffset), + localStyle.stroke); + } else { + canvas.drawPath(path, localStyle.stroke); + } } - if (style?.fill != null) { - canvas.drawPath(path, style.fill); - } else if (parentStyle?.fill != null) { - canvas.drawPath(path, parentStyle.fill); + if (localStyle?.fill != null) { + canvas.drawPath(path, localStyle.fill); } else { canvas.drawPath(path, _blackPaint); } diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index b2801aba70e8..9a92a366bc33 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -234,7 +234,7 @@ packages: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.1.1" + version: "0.2.2" petitparser: dependency: transitive description: @@ -409,5 +409,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.c080951d45e79cd25df98036c4be835b284a269c" + dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.0d5cf900b021bf5c9fa593ffa12b15bcd1cc5fe0" flutter: ">=0.3.6 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 9c96b8fddac3..530acf4a1b3d 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/dnfield/flutter_svg version: 0.0.2 dependencies: - path_drawing: ^0.1.1 + path_drawing: ^0.2.2 xml: ^3.0.0 vector_math: ^2.0.4 meta: ^1.1.2 @@ -54,10 +54,11 @@ flutter: - assets/simple/linear_gradient.svg - assets/simple/linear_gradient_2.svg - assets/simple/radial_gradient.svg + - assets/simple/dash_path.svg - assets/simple/text.svg - assets/wikimedia/Ghostscript_Tiger.svg - assets/android_vd/battery_charging.xml environment: - sdk: ">=1.19.0" + sdk: ">=1.19.0 <3.0.0" flutter: ">=0.3.6 <2.0.0" From 925f0b7e63bb0920dfef48068197b9ab0eb5852d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 10 May 2018 16:02:48 -0400 Subject: [PATCH 042/512] basic support for style attribute, better inheritence, bump version --- third_party/CHANGELOG.md | 17 ++++- third_party/assets/simple/rect_rrect.svg | 2 +- third_party/assets/simple/style_attr.svg | 6 ++ third_party/lib/avd.dart | 3 +- third_party/lib/main.dart | 10 +-- third_party/lib/src/avd/xml_parsers.dart | 55 ++++++++------ third_party/lib/src/avd_parser.dart | 6 +- third_party/lib/src/svg/colors.dart | 25 ++++++- third_party/lib/src/svg/parsers.dart | 9 +++ third_party/lib/src/svg/xml_parsers.dart | 28 +++---- third_party/lib/src/svg_parser.dart | 93 ++++++++++++------------ third_party/lib/src/utilities/xml.dart | 28 ++++++- third_party/lib/src/vector_painter.dart | 39 ++++++---- third_party/lib/svg.dart | 7 +- third_party/pubspec.lock | 2 +- third_party/pubspec.yaml | 3 +- 16 files changed, 218 insertions(+), 115 deletions(-) create mode 100644 third_party/assets/simple/style_attr.svg diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 0fa8f03e2118..9b545536267f 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,9 +1,20 @@ # CHANGES -## 0.0.1 +## 0.1.0 -Initial release. Relies on pre-released master +Bumping minor version due to internal breaking changes and new support. Works on dev channel as of release (Flutter >= 0.3.6). + +- Refactor `DrawableRoot` to support top level style definition. +- Support for dash paths. +- Support for more inherited attributes. +- Initial support for `@style` attributes. +- Support for `rgb()` color attribute/styles. +- Change painting order from stroke first, then fill to fill first, then stroke (matches Chrome rendering of `assets/simple/style_attr.svg`). ## 0.0.2 -Initial text support. Relies on flutter 0.3.6 \ No newline at end of file +Initial text support. Relies on flutter 0.3.6 + +## 0.0.1 + +Initial release. Relies on pre-released master diff --git a/third_party/assets/simple/rect_rrect.svg b/third_party/assets/simple/rect_rrect.svg index fea9e855cfb5..5960d185df26 100644 --- a/third_party/assets/simple/rect_rrect.svg +++ b/third_party/assets/simple/rect_rrect.svg @@ -2,5 +2,5 @@ - + diff --git a/third_party/assets/simple/style_attr.svg b/third_party/assets/simple/style_attr.svg new file mode 100644 index 000000000000..1c42fd79dd0f --- /dev/null +++ b/third_party/assets/simple/style_attr.svg @@ -0,0 +1,6 @@ + + + diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 70531f2471e1..193a62bbe4dd 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -75,7 +75,8 @@ DrawableRoot fromAvdString(String rawSvg, Size size) { new Rect.fromPoints( Offset.zero, new Offset(size.width, size.height)))) .toList(); - return new DrawableRoot(viewBox, children, {}); + // todo : style on root + return new DrawableRoot(viewBox, children, {}, null); } /// Creates a [DrawableRoot] from a bundled asset. diff --git a/third_party/lib/main.dart b/third_party/lib/main.dart index e9bffba73a8a..c32df641ac3c 100644 --- a/third_party/lib/main.dart +++ b/third_party/lib/main.dart @@ -10,6 +10,7 @@ const List assetNames = const [ 'assets/simple/linear_gradient_2.svg', 'assets/simple/radial_gradient.svg', 'assets/simple/rect_rrect.svg', + 'assets/simple/style_attr.svg', 'assets/w3samples/aa.svg', 'assets/w3samples/alphachannel.svg', 'assets/deborah_ufw/new-action-expander.svg', @@ -29,8 +30,8 @@ const List assetNames = const [ ]; const List uriNames = const [ - 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', + // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', ]; void main() => runApp(new MyApp()); @@ -90,9 +91,8 @@ class _MyHomePageState extends State { @override Widget build(BuildContext context) { - - if ( _dimension > MediaQuery.of(context).size.width - 10.0){ - _dimension = MediaQuery.of(context).size.width - 10.0; + if (_dimension > MediaQuery.of(context).size.width - 10.0) { + _dimension = MediaQuery.of(context).size.width - 10.0; } return new Scaffold( appBar: new AppBar( diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index cb45f2cd239a..0bdae0f6c947 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -11,8 +11,10 @@ const String androidNS = 'http://schemas.android.com/apk/res/android'; /// Parses an AVD @android:viewportWidth and @android:viewportHeight attributes to a [Rect]. Rect parseViewBox(XmlElement el) { - final String rawWidth = getAttribute(el, 'viewportWidth', '', androidNS); - final String rawHeight = getAttribute(el, 'viewportHeight', '', androidNS); + final String rawWidth = + getAttribute(el, 'viewportWidth', def: '', namespace: androidNS); + final String rawHeight = + getAttribute(el, 'viewportHeight', def: '', namespace: androidNS); if (rawWidth == '' || rawHeight == '') { return Rect.zero; } @@ -22,15 +24,20 @@ Rect parseViewBox(XmlElement el) { } Matrix4 parseTransform(XmlElement el) { - double rotation = double.parse(getAttribute(el, 'rotation', '0', androidNS)); - double pivotX = double.parse(getAttribute(el, 'pivotX', '0', androidNS)); - double pivotY = double.parse(getAttribute(el, 'pivotY', '0', androidNS)); - double scaleX = double.parse(getAttribute(el, 'scaleX', '1', androidNS)); - double scaleY = double.parse(getAttribute(el, 'scaleY', '1', androidNS)); - double translateX = - double.parse(getAttribute(el, 'translateX', '0', androidNS)); - double translateY = - double.parse(getAttribute(el, 'translateY', '0', androidNS)); + double rotation = double + .parse(getAttribute(el, 'rotation', def: '0', namespace: androidNS)); + double pivotX = + double.parse(getAttribute(el, 'pivotX', def: '0', namespace: androidNS)); + double pivotY = + double.parse(getAttribute(el, 'pivotY', def: '0', namespace: androidNS)); + double scaleX = + double.parse(getAttribute(el, 'scaleX', def: '1', namespace: androidNS)); + double scaleY = + double.parse(getAttribute(el, 'scaleY', def: '1', namespace: androidNS)); + double translateX = double + .parse(getAttribute(el, 'translateX', def: '0', namespace: androidNS)); + double translateY = double + .parse(getAttribute(el, 'translateY', def: '0', namespace: androidNS)); return new Matrix4.identity() ..translate(pivotX, pivotY) @@ -40,28 +47,30 @@ Matrix4 parseTransform(XmlElement el) { } Paint parseStroke(XmlElement el, Rect bounds) { - final String rawStroke = getAttribute(el, 'strokeColor', null, androidNS); + final String rawStroke = + getAttribute(el, 'strokeColor', def: null, namespace: androidNS); if (rawStroke == null) { return null; } return new Paint() ..style = PaintingStyle.stroke - ..color = parseColor(rawStroke) - .withOpacity(double.parse(getAttribute(el, 'strokeAlpha', '1'))) - ..strokeWidth = - double.parse(getAttribute(el, 'strokeWidth', '0', androidNS)) + ..color = parseColor(rawStroke).withOpacity(double + .parse(getAttribute(el, 'strokeAlpha', def: '1', namespace: androidNS))) + ..strokeWidth = double + .parse(getAttribute(el, 'strokeWidth', def: '0', namespace: androidNS)) ..strokeCap = parseStrokeCap(el) ..strokeJoin = parseStrokeJoin(el) ..strokeMiterLimit = parseMiterLimit(el); } double parseMiterLimit(XmlElement el) { - return double.parse(getAttribute(el, 'strokeMiterLimit', '4', androidNS)); + return double.parse( + getAttribute(el, 'strokeMiterLimit', def: '4', namespace: androidNS)); } StrokeJoin parseStrokeJoin(XmlElement el) { final String rawStrokeJoin = - getAttribute(el, 'strokeLineJoin', 'miter', androidNS); + getAttribute(el, 'strokeLineJoin', def: 'miter', namespace: androidNS); switch (rawStrokeJoin) { case 'miter': return StrokeJoin.miter; @@ -76,7 +85,7 @@ StrokeJoin parseStrokeJoin(XmlElement el) { StrokeCap parseStrokeCap(XmlElement el) { final String rawStrokeCap = - getAttribute(el, 'strokeLineCap', 'butt', androidNS); + getAttribute(el, 'strokeLineCap', def: 'butt', namespace: androidNS); switch (rawStrokeCap) { case 'butt': return StrokeCap.butt; @@ -90,17 +99,19 @@ StrokeCap parseStrokeCap(XmlElement el) { } Paint parseFill(XmlElement el, Rect bounds) { - final String rawFill = getAttribute(el, 'fillColor', null, androidNS); + final String rawFill = + getAttribute(el, 'fillColor', def: null, namespace: androidNS); if (rawFill == null) { return null; } return new Paint() ..style = PaintingStyle.fill ..color = parseColor(rawFill) - .withOpacity(double.parse(getAttribute(el, 'fillAlpha', '1'))); + .withOpacity(double.parse(getAttribute(el, 'fillAlpha', def: '1'))); } PathFillType parsePathFillType(XmlElement el) { - final String rawFillType = getAttribute(el, 'fillType', 'nonZero', androidNS); + final String rawFillType = + getAttribute(el, 'fillType', def: 'nonZero', namespace: androidNS); return rawFillType == 'nonZero' ? PathFillType.nonZero : PathFillType.evenOdd; } diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index b51124b3a0b5..04bd69c7c3b7 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -10,8 +10,8 @@ import 'utilities/xml.dart'; class DrawableAvdRoot extends DrawableRoot { const DrawableAvdRoot(Rect viewBox, List children, - Map paintServers) - : super(viewBox, children, paintServers); + Map paintServers, DrawableStyle style) + : super(viewBox, children, paintServers, style); } /// An SVG Shape element that will be drawn to the canvas. @@ -20,7 +20,7 @@ class DrawableAvdPath extends DrawableShape { /// Creates a [DrawableAvdPath] from an XML element factory DrawableAvdPath.fromXml(XmlElement el) { - final d = getAttribute(el, 'pathData', '', androidNS); + final d = getAttribute(el, 'pathData', def: '', namespace: androidNS); final Path path = parseSvgPathData(d); assert(path != null); diff --git a/third_party/lib/src/svg/colors.dart b/third_party/lib/src/svg/colors.dart index e8fb9ee62352..1be29223185e 100644 --- a/third_party/lib/src/svg/colors.dart +++ b/third_party/lib/src/svg/colors.dart @@ -8,6 +8,7 @@ Color parseColor(String colorString) { return colorBlack; } + // handle hex colors e.g. #fff or #ffffff. This supports #RRGGBBAA if (colorString[0] == '#') { if (colorString.length == 4) { final r = colorString[1]; @@ -26,13 +27,35 @@ Color parseColor(String colorString) { } } + // handle rgb() colors e.g. rgb(255, 255, 255) + if (colorString.startsWith('rgb')) { + final List rgb = colorString + .substring(colorString.indexOf('(') + 1, colorString.indexOf(')')) + .split(',') + .map( + (String rawColor) { + if (rawColor.endsWith('%')) { + final int percentage = + int.parse(rawColor.substring(0, rawColor.length - 1)); + return (percentage * 2.55).round(); + } + return int.parse(rawColor); + }, + ).toList(); + + // rgba() isn't really in the spec, but Firefox supported it at one point so why not. + final int a = rgb.length > 3 ? rgb[3] : 255; + return new Color.fromARGB(a, rgb[0], rgb[1], rgb[2]); + } + + // handle named colors ('red', 'green', etc.). final namedColor = _namedColors[colorString]; if (namedColor != null) { return namedColor; } throw new ArgumentError.value( - colorString, 'colorString', 'Unknown color $colorString'); + colorString, 'colorString', 'Incorrectly formatted color $colorString'); } // https://www.w3.org/TR/SVG11/types.html#ColorKeywords diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index 5e21a80f7c3c..ad10ec48fc71 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -1,4 +1,5 @@ import 'dart:math'; +import 'dart:ui'; import 'package:vector_math/vector_math_64.dart'; @@ -112,3 +113,11 @@ Matrix4 _matrix(double a, double b, double c, double d, double e, double f) { return new Matrix4( a, b, 0.0, 0.0, c, d, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, e, f, 0.0, 1.0); } + + +PathFillType parseRawFillRule(String rawFillRule) { + if (rawFillRule == '' || rawFillRule == null) { + return PathFillType.nonZero; + } + return rawFillRule != 'nonzero' ? PathFillType.evenOdd : PathFillType.nonZero; +} \ No newline at end of file diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 985e0095109e..52e54179a7bb 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -6,6 +6,7 @@ import 'package:xml/xml.dart'; import '../vector_painter.dart'; import '../utilities/xml.dart'; import 'colors.dart'; +import 'parsers.dart'; /// Parses an SVG @viewBox attribute (e.g. 0 0 100 100) to a [Rect]. Rect parseViewBox(XmlElement svg) { @@ -59,10 +60,10 @@ double _parseDecimalOrPercentage(String val) { /// Parses an SVG element into a [Paint]. Paint parseLinearGradient(XmlElement el, Rect bounds) { - final double x1 = _parseDecimalOrPercentage(getAttribute(el, 'x1', '0%')); - final double x2 = _parseDecimalOrPercentage(getAttribute(el, 'x2', '100%')); - final double y1 = _parseDecimalOrPercentage(getAttribute(el, 'y1', '0%')); - final double y2 = _parseDecimalOrPercentage(getAttribute(el, 'y2', '0%')); + final double x1 = _parseDecimalOrPercentage(getAttribute(el, 'x1', def: '0%')); + final double x2 = _parseDecimalOrPercentage(getAttribute(el, 'x2', def: '100%')); + final double y1 = _parseDecimalOrPercentage(getAttribute(el, 'y1', def: '0%')); + final double y2 = _parseDecimalOrPercentage(getAttribute(el, 'y2', def: '0%')); final Offset from = new Offset( bounds.left + (bounds.width * x1), @@ -78,7 +79,7 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { from, to, stops.map((stop) { - final String rawOpacity = getAttribute(stop, 'stop-opacity', '1'); + final String rawOpacity = getAttribute(stop, 'stop-opacity', def: '1'); return parseColor(getAttribute(stop, 'stop-color')) .withOpacity(double.parse(rawOpacity)); }).toList(), @@ -93,13 +94,13 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { /// Parses a into a [Paint]. Paint parseRadialGradient(XmlElement el, Rect bounds) { - final String rawCx = getAttribute(el, 'cx', '50%'); - final String rawCy = getAttribute(el, 'cy', '50%'); + final String rawCx = getAttribute(el, 'cx', def: '50%'); + final String rawCy = getAttribute(el, 'cy', def: '50%'); final double cx = _parseDecimalOrPercentage(rawCx); final double cy = _parseDecimalOrPercentage(rawCy); - final double r = _parseDecimalOrPercentage(getAttribute(el, 'r', '50%')); - final double fx = _parseDecimalOrPercentage(getAttribute(el, 'fx', rawCx)); - final double fy = _parseDecimalOrPercentage(getAttribute(el, 'fy', rawCy)); + final double r = _parseDecimalOrPercentage(getAttribute(el, 'r', def: '50%')); + final double fx = _parseDecimalOrPercentage(getAttribute(el, 'fx', def: rawCx)); + final double fy = _parseDecimalOrPercentage(getAttribute(el, 'fy', def: rawCy)); if (fx != cx || fy != cy) { throw new UnsupportedError( @@ -111,7 +112,7 @@ Paint parseRadialGradient(XmlElement el, Rect bounds) { new Offset(cx, cy), r, stops.map((stop) { - final String rawOpacity = getAttribute(stop, 'stop-opacity', '1'); + final String rawOpacity = getAttribute(stop, 'stop-opacity', def: '1'); return parseColor(getAttribute(stop, 'stop-color')) .withOpacity(double.parse(rawOpacity)); }).toList(), @@ -237,6 +238,7 @@ Paint parseFill( } PathFillType parseFillRule(XmlElement el) { - final String rawFillRule = getAttribute(el, 'fill-rule', 'nonzero'); - return rawFillRule == 'nonzero' ? PathFillType.nonZero : PathFillType.evenOdd; + final String rawFillRule = getAttribute(el, 'fill-rule', def: 'nonzero'); + return parseRawFillRule(rawFillRule); } + diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 1f453eef07bb..0218478dbebe 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -40,7 +40,7 @@ class DrawableSvgShape extends DrawableShape { assert(el != null); final Matrix4 transform = - parseTransform(getAttribute(el, 'transform', null)); + parseTransform(getAttribute(el, 'transform', def: null)); if (transform != null) { return path.transform(transform.storage); @@ -52,27 +52,19 @@ class DrawableSvgShape extends DrawableShape { static _createDrawable( Path path, Map paintServers, XmlElement el) { assert(path != null); - final stroke = parseStroke(el, path.getBounds(), paintServers); - final fill = parseFill(el, path.getBounds(), paintServers); - path.fillType = parseFillRule(el); return new DrawableSvgShape( transformPath(path, el), - new DrawableStyle( - fill: fill, - stroke: stroke, - dashArray: parseDashArray(el), - dashOffset: parseDashOffset(el), - ), + parseStyle(el, paintServers, path.getBounds()), ); } /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgCircle( XmlElement el, Map paintServers) { - final cx = double.parse(getAttribute(el, 'cx', '0')); - final cy = double.parse(getAttribute(el, 'cy', '0')); - final r = double.parse(getAttribute(el, 'r', '0')); + final cx = double.parse(getAttribute(el, 'cx', def: '0')); + final cy = double.parse(getAttribute(el, 'cy', def: '0')); + final r = double.parse(getAttribute(el, 'r', def: '0')); final oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); final path = new Path()..addOval(oval); @@ -90,13 +82,13 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgRect( XmlElement el, Map paintServers) { - final double x = double.parse(getAttribute(el, 'x', '0')); - final double y = double.parse(getAttribute(el, 'y', '0')); - final double w = double.parse(getAttribute(el, 'width', '0')); - final double h = double.parse(getAttribute(el, 'height', '0')); + final double x = double.parse(getAttribute(el, 'x', def: '0')); + final double y = double.parse(getAttribute(el, 'y', def: '0')); + final double w = double.parse(getAttribute(el, 'width', def: '0')); + final double h = double.parse(getAttribute(el, 'height', def: '0')); final Rect rect = new Rect.fromLTWH(x, y, w, h); - String rxRaw = getAttribute(el, 'rx', '0'); - String ryRaw = getAttribute(el, 'ry', '0'); + String rxRaw = getAttribute(el, 'rx', def: '0'); + String ryRaw = getAttribute(el, 'ry', def: '0'); rxRaw ??= ryRaw; ryRaw ??= rxRaw; @@ -130,10 +122,10 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgEllipse( XmlElement el, Map paintServers) { - final cx = double.parse(getAttribute(el, 'cx', '0')); - final cy = double.parse(getAttribute(el, 'cy', '0')); - final rx = double.parse(getAttribute(el, 'rx', '0')); - final ry = double.parse(getAttribute(el, 'ry', '0')); + final cx = double.parse(getAttribute(el, 'cx', def: '0')); + final cy = double.parse(getAttribute(el, 'cy', def: '0')); + final rx = double.parse(getAttribute(el, 'rx', def: '0')); + final ry = double.parse(getAttribute(el, 'ry', def: '0')); Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); @@ -143,10 +135,10 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgLine( XmlElement el, Map paintServers) { - final x1 = double.parse(getAttribute(el, 'x1', '0')); - final x2 = double.parse(getAttribute(el, 'x2', '0')); - final y1 = double.parse(getAttribute(el, 'y1', '0')); - final y2 = double.parse(getAttribute(el, 'y2', '0')); + final x1 = double.parse(getAttribute(el, 'x1', def: '0')); + final x2 = double.parse(getAttribute(el, 'x2', def: '0')); + final y1 = double.parse(getAttribute(el, 'y1', def: '0')); + final y2 = double.parse(getAttribute(el, 'y2', def: '0')); final path = new Path() ..moveTo(x1, y1) @@ -179,20 +171,21 @@ Drawable parseSvgElement( Drawable parseSvgText( XmlElement el, Map paintServers, Rect bounds) { - final Offset offset = new Offset(double.parse(getAttribute(el, 'x', '0')), - double.parse(getAttribute(el, 'y', '0'))); + final Offset offset = new Offset( + double.parse(getAttribute(el, 'x', def: '0')), + double.parse(getAttribute(el, 'y', def: '0'))); return new DrawableText( el.text, offset, new DrawableStyle( textStyle: new TextStyle( fontFamily: getAttribute(el, 'font-family'), - fontSize: double.parse(getAttribute(el, 'font-size', '55')), + fontSize: double.parse(getAttribute(el, 'font-size', def: '55')), color: parseColor( getAttribute( el, 'fill', - getAttribute(el, 'stroke', 'black'), + def: getAttribute(el, 'stroke', def: 'black'), ), ), height: -1.0, @@ -214,22 +207,32 @@ Drawable parseSvgGroup( } }); - final Matrix4 transform = parseTransform(getAttribute(el, 'transform')); + return new DrawableGroup( + children, + //TODO: when Dart2 is around use this instead of above + // el.children + // .whereType() + // .map((child) => new SvgBaseElement.fromXml(child)), + parseStyle(el, paintServers, bounds, needsTransform: true)); +} + +/// Parses style attributes or @style attribute. +/// +/// Remember that @style attribute takes precedence. +DrawableStyle parseStyle( + XmlElement el, Map paintServers, Rect bounds, + {bool needsTransform = false}) { + final Matrix4 transform = + needsTransform ? parseTransform(getAttribute(el, 'transform')) : null; final Paint fill = parseFill(el, bounds, paintServers); final Paint stroke = parseStroke(el, bounds, paintServers); - return new DrawableGroup( - children, - //TODO: when Dart2 is around use this instead of above - // el.children - // .whereType() - // .map((child) => new SvgBaseElement.fromXml(child)), - new DrawableStyle( - transform: transform?.storage, - stroke: stroke, - dashArray: parseDashArray(el), - dashOffset: parseDashOffset(el), - fill: fill, - ), + return new DrawableStyle( + transform: transform?.storage, + stroke: stroke, + dashArray: parseDashArray(el), + dashOffset: parseDashOffset(el), + fill: fill, + pathFillType: parseFillRule(el), ); } diff --git a/third_party/lib/src/utilities/xml.dart b/third_party/lib/src/utilities/xml.dart index 2ed59bdd22e0..46a6c5d78218 100644 --- a/third_party/lib/src/utilities/xml.dart +++ b/third_party/lib/src/utilities/xml.dart @@ -2,7 +2,29 @@ import 'package:xml/xml.dart'; /// Gets the attribute, trims it, and returns the attribute or default if the attribute /// is null or ''. -String getAttribute(XmlElement el, String name, [String def = '', String namespace]) { - final String raw = el.getAttribute(name, namespace: namespace)?.trim(); +/// +/// Will look to the style first if it can. +String getAttribute(XmlElement el, String name, + {String def = '', String namespace, bool checkStyle = true}) { + String raw = ''; + if (checkStyle) { + final String style = el.getAttribute('style')?.trim(); + if (style != '' && style != null) { + final List styles = style.split(';'); + raw = styles.firstWhere((str) => str.trimLeft().startsWith(name + ':'), + orElse: () => ''); + + if (raw != '') { + raw = raw.substring(raw.indexOf(':') + 1)?.trim(); + } + } + + if (raw == '' || raw == null) { + raw = el.getAttribute(name, namespace: namespace)?.trim(); + } + } else { + raw = el.getAttribute(name, namespace: namespace)?.trim(); + } + return raw == '' || raw == null ? def : raw; -} \ No newline at end of file +} diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 2e7d378ef5c0..7fa3378bd497 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -26,6 +26,7 @@ class DrawableStyle { final Paint fill; final Float64List transform; final TextStyle textStyle; + final PathFillType pathFillType; const DrawableStyle( {this.stroke, @@ -33,7 +34,8 @@ class DrawableStyle { this.dashOffset, this.fill, this.transform, - this.textStyle}); + this.textStyle, + this.pathFillType}); /// Creates a new [DrawableStyle] if `other` is not null, filling in any null properties on /// this with the properties from other. @@ -43,12 +45,14 @@ class DrawableStyle { if (other == null) return this; return new DrawableStyle( - fill: this.fill ?? other.fill, - stroke: this.stroke ?? other.stroke, - dashArray: this.dashArray ?? other.dashArray, - dashOffset: this.dashOffset ?? other.dashOffset, - transform: this.transform ?? other.transform, - textStyle: this.textStyle ?? other.textStyle); + fill: this.fill ?? other.fill, + stroke: this.stroke ?? other.stroke, + dashArray: this.dashArray ?? other.dashArray, + dashOffset: this.dashOffset ?? other.dashOffset, + transform: this.transform ?? other.transform, + textStyle: this.textStyle ?? other.textStyle, + pathFillType: this.pathFillType ?? other.pathFillType, + ); } } @@ -88,7 +92,10 @@ class DrawableRoot implements Drawable { final Map paintServers; - const DrawableRoot(this.viewBox, this.children, this.paintServers); + final DrawableStyle style; + + const DrawableRoot( + this.viewBox, this.children, this.paintServers, this.style); /// Scales the `canvas` so that the drawing units in this [Drawable] /// will scale to the `desiredSize`. @@ -124,7 +131,8 @@ class DrawableRoot implements Drawable { @override void draw(Canvas canvas, [DrawableStyle parentStyle]) { - children.forEach((child) => child.draw(canvas, parentStyle)); + children.forEach((child) => + child.draw(canvas, style?.merge(parentStyle) ?? parentStyle)); } } @@ -183,6 +191,13 @@ class DrawableShape implements Drawable { void draw(Canvas canvas, [DrawableStyle parentStyle]) { final DrawableStyle localStyle = style.merge(parentStyle); + path.fillType = localStyle.pathFillType ?? PathFillType.nonZero; + + if (localStyle?.fill != null) { + canvas.drawPath(path, localStyle.fill); + } else { + canvas.drawPath(path, _blackPaint); + } if (localStyle?.stroke != null) { if (localStyle.dashArray != null) { canvas.drawPath( @@ -194,12 +209,6 @@ class DrawableShape implements Drawable { canvas.drawPath(path, localStyle.stroke); } } - - if (localStyle?.fill != null) { - canvas.drawPath(path, localStyle.fill); - } else { - canvas.drawPath(path, _blackPaint); - } } } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 7c38695bb425..53cedfcc824a 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -77,7 +77,12 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { new Rect.fromPoints( Offset.zero, new Offset(size.width, size.height)))) .toList(); - return new DrawableRoot(viewBox, children, {}); + return new DrawableRoot( + viewBox, + children, + paintServers, + parseStyle(svg, paintServers, viewBox), + ); } /// Creates a [DrawableRoot] from a bundled asset. diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 9a92a366bc33..3a4d8d0ec7b1 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -409,5 +409,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.0d5cf900b021bf5c9fa593ffa12b15bcd1cc5fe0" + dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.c080951d45e79cd25df98036c4be835b284a269c" flutter: ">=0.3.6 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 530acf4a1b3d..a0cd62b58853 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.0.2 +version: 0.1.0 dependencies: path_drawing: ^0.2.2 @@ -56,6 +56,7 @@ flutter: - assets/simple/radial_gradient.svg - assets/simple/dash_path.svg - assets/simple/text.svg + - assets/simple/style_attr.svg - assets/wikimedia/Ghostscript_Tiger.svg - assets/android_vd/battery_charging.xml From e74d8081d063a9757880af9c42c35661a2efea59 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 10 May 2018 16:15:01 -0400 Subject: [PATCH 043/512] add some tests, update travis to point to dev --- third_party/.travis.yml | 2 +- third_party/test/xml_test.dart | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/third_party/.travis.yml b/third_party/.travis.yml index 231ccc6f3251..bb9518ad4a53 100644 --- a/third_party/.travis.yml +++ b/third_party/.travis.yml @@ -10,7 +10,7 @@ addons: - libstdc++6 - fonts-droid before_script: - - git clone https://github.com/flutter/flutter.git -b master + - git clone https://github.com/flutter/flutter.git -b dev - ./flutter/bin/flutter doctor script: - ./flutter/bin/flutter test diff --git a/third_party/test/xml_test.dart b/third_party/test/xml_test.dart index e6dae2e83994..aa1cc4867392 100644 --- a/third_party/test/xml_test.dart +++ b/third_party/test/xml_test.dart @@ -4,8 +4,21 @@ import 'package:test/test.dart'; import 'package:xml/xml.dart'; import 'package:flutter_svg/src/svg/xml_parsers.dart'; +import 'package:flutter_svg/src/utilities/xml.dart'; void main() { + test('Attribute and style tests', () { + final XmlElement el = parse( + '') + .rootElement; + + expect(getAttribute(el, 'stroke'), '#fff'); + expect(getAttribute(el, 'fill'), '#eee'); + expect(getAttribute(el, 'stroke-dashpattern'), '1 2'); + expect(getAttribute(el, 'stroke-opacity'), '1'); + expect(getAttribute(el, 'stroke-another'), ''); + expect(getAttribute(el, 'fill-opacity'), '.23'); + }); // if the parsing logic changes, we can simplify some methods. for now assert that whitespace in attributes is preserved test('Attribute WhiteSpace test', () { XmlDocument xd = From 058264a692d3e9f981ff8c499972e30e758c8d7e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 10 May 2018 16:22:39 -0400 Subject: [PATCH 044/512] comment after experimenting with optimizations --- third_party/lib/src/utilities/xml.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/third_party/lib/src/utilities/xml.dart b/third_party/lib/src/utilities/xml.dart index 46a6c5d78218..69f1326b424e 100644 --- a/third_party/lib/src/utilities/xml.dart +++ b/third_party/lib/src/utilities/xml.dart @@ -10,6 +10,9 @@ String getAttribute(XmlElement el, String name, if (checkStyle) { final String style = el.getAttribute('style')?.trim(); if (style != '' && style != null) { + // Probably possible to slightly optimize this (e.g. use indexOf instead of split), + // but handling potential whitespace will get complicated and this just works. + // I also don't feel like writing benchmarks for what is likely a micro-optimization. final List styles = style.split(';'); raw = styles.firstWhere((str) => str.trimLeft().startsWith(name + ':'), orElse: () => ''); From 51e48b54ed6cf84f15f698e49c0d5935d0e7e65c Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 11 May 2018 00:34:58 -0400 Subject: [PATCH 045/512] move example, improved inheritence, improved opacity handling --- third_party/assets/dart.svg | 50 +++++++++ third_party/assets/simple/group_opacity.svg | 46 ++++++++ third_party/assets/simple/nested_group.svg | 5 +- third_party/{lib => example}/main.dart | 11 +- third_party/lib/src/avd_parser.dart | 1 + third_party/lib/src/svg/colors.dart | 9 +- third_party/lib/src/svg/xml_parsers.dart | 59 ++++++---- third_party/lib/src/svg_parser.dart | 117 ++++++++++++-------- third_party/lib/src/vector_painter.dart | 46 ++++++-- third_party/lib/svg.dart | 18 ++- third_party/pubspec.lock | 55 +++------ third_party/pubspec.yaml | 2 + 12 files changed, 285 insertions(+), 134 deletions(-) create mode 100644 third_party/assets/dart.svg create mode 100644 third_party/assets/simple/group_opacity.svg rename third_party/{lib => example}/main.dart (90%) diff --git a/third_party/assets/dart.svg b/third_party/assets/dart.svg new file mode 100644 index 000000000000..261e2bbf97da --- /dev/null +++ b/third_party/assets/dart.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/assets/simple/group_opacity.svg b/third_party/assets/simple/group_opacity.svg new file mode 100644 index 000000000000..1bc0a7a7f548 --- /dev/null +++ b/third_party/assets/simple/group_opacity.svg @@ -0,0 +1,46 @@ + + + + Example opacity01 - opacity property + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/assets/simple/nested_group.svg b/third_party/assets/simple/nested_group.svg index 33270267295a..6f8472319a67 100644 --- a/third_party/assets/simple/nested_group.svg +++ b/third_party/assets/simple/nested_group.svg @@ -1,9 +1,8 @@ - - - + + \ No newline at end of file diff --git a/third_party/lib/main.dart b/third_party/example/main.dart similarity index 90% rename from third_party/lib/main.dart rename to third_party/example/main.dart index c32df641ac3c..d25f67f2835e 100644 --- a/third_party/lib/main.dart +++ b/third_party/example/main.dart @@ -5,6 +5,8 @@ import 'package:flutter_svg/svg.dart'; const List assetNames = const [ 'assets/flutter_logo.svg', + 'assets/dart.svg', + 'assets/simple/group_opacity.svg', 'assets/simple/text.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', @@ -30,8 +32,8 @@ const List assetNames = const [ ]; const List uriNames = const [ - // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', + 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', ]; void main() => runApp(new MyApp()); @@ -67,9 +69,6 @@ class _MyHomePageState extends State { super.initState(); _dimension = 365.0; - _painters.add(new AvdImage.asset('assets/android_vd/battery_charging.xml', - new Size(_dimension, _dimension))); - assetNames.forEach((assetName) { _painters.add( new SvgImage.asset( @@ -87,6 +86,8 @@ class _MyHomePageState extends State { ), ); }); + // _painters.add(new AvdImage.asset('assets/android_vd/battery_charging.xml', + // new Size(_dimension, _dimension))); } @override diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index 04bd69c7c3b7..e5f80347931c 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -72,6 +72,7 @@ Drawable parseAvdGroup(XmlElement el, Rect bounds) { transform: transform?.storage, stroke: stroke, fill: fill, + groupOpacity: 1.0, ), ); } diff --git a/third_party/lib/src/svg/colors.dart b/third_party/lib/src/svg/colors.dart index 1be29223185e..b3be7bd8b226 100644 --- a/third_party/lib/src/svg/colors.dart +++ b/third_party/lib/src/svg/colors.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -const colorBlack = const Color.fromARGB(255, 0, 0, 0); +const colorBlack = const Color(0xFF000000); /// Converts a SVG Color String (either a # prefixed color string or a named color) to a [Color]. Color parseColor(String colorString) { @@ -8,6 +8,10 @@ Color parseColor(String colorString) { return colorBlack; } + if (colorString == 'none') { + return null; + } + // handle hex colors e.g. #fff or #ffffff. This supports #RRGGBBAA if (colorString[0] == '#') { if (colorString.length == 4) { @@ -19,7 +23,7 @@ Color parseColor(String colorString) { int color = int.parse(colorString.substring(1), radix: 16); if (colorString.length == 7) { - return new Color(color |= 0x00000000ff000000); + return new Color(color |= 0xFF000000); } if (colorString.length == 9) { @@ -60,7 +64,6 @@ Color parseColor(String colorString) { // https://www.w3.org/TR/SVG11/types.html#ColorKeywords const Map _namedColors = const { - 'none': const Color(0), 'aliceblue': const Color.fromARGB(255, 240, 248, 255), 'antiquewhite': const Color.fromARGB(255, 250, 235, 215), 'aqua': const Color.fromARGB(255, 0, 255, 255), diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 52e54179a7bb..f95dd6c30cb5 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -60,10 +60,14 @@ double _parseDecimalOrPercentage(String val) { /// Parses an SVG element into a [Paint]. Paint parseLinearGradient(XmlElement el, Rect bounds) { - final double x1 = _parseDecimalOrPercentage(getAttribute(el, 'x1', def: '0%')); - final double x2 = _parseDecimalOrPercentage(getAttribute(el, 'x2', def: '100%')); - final double y1 = _parseDecimalOrPercentage(getAttribute(el, 'y1', def: '0%')); - final double y2 = _parseDecimalOrPercentage(getAttribute(el, 'y2', def: '0%')); + final double x1 = + _parseDecimalOrPercentage(getAttribute(el, 'x1', def: '0%')); + final double x2 = + _parseDecimalOrPercentage(getAttribute(el, 'x2', def: '100%')); + final double y1 = + _parseDecimalOrPercentage(getAttribute(el, 'y1', def: '0%')); + final double y2 = + _parseDecimalOrPercentage(getAttribute(el, 'y2', def: '0%')); final Offset from = new Offset( bounds.left + (bounds.width * x1), @@ -99,8 +103,10 @@ Paint parseRadialGradient(XmlElement el, Rect bounds) { final double cx = _parseDecimalOrPercentage(rawCx); final double cy = _parseDecimalOrPercentage(rawCy); final double r = _parseDecimalOrPercentage(getAttribute(el, 'r', def: '50%')); - final double fx = _parseDecimalOrPercentage(getAttribute(el, 'fx', def: rawCx)); - final double fy = _parseDecimalOrPercentage(getAttribute(el, 'fy', def: rawCy)); + final double fx = + _parseDecimalOrPercentage(getAttribute(el, 'fx', def: rawCx)); + final double fy = + _parseDecimalOrPercentage(getAttribute(el, 'fy', def: rawCy)); if (fx != cx || fy != cy) { throw new UnsupportedError( @@ -166,11 +172,20 @@ DashOffset parseDashOffset(XmlElement el) { } } +/// Parses an @opacity value into a [double], clamped between 0..1. +double parseOpacity(XmlElement el) { + final String rawOpacity = getAttribute(el, 'opacity', def: null); + if (rawOpacity != null) { + return double.parse(rawOpacity).clamp(0.0, 1.0); + } + return null; +} + /// Parses a @stroke attribute into a [Paint]. Paint parseStroke( XmlElement el, Rect bounds, Map paintServers) { - final rawStroke = getAttribute(el, 'stroke'); - if (rawStroke == '') { + final rawStroke = getAttribute(el, 'stroke', def: 'none'); + if (rawStroke == 'none') { return null; } @@ -178,9 +193,7 @@ Paint parseStroke( return paintServers[rawStroke](bounds); } var rawOpacity = getAttribute(el, 'stroke-opacity'); - if (rawOpacity == '') { - rawOpacity = getAttribute(el, 'opacity'); - } + final double opacity = rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); final Paint paint = new Paint() @@ -211,10 +224,16 @@ Paint parseStroke( return paint; } -Paint parseFill( - XmlElement el, Rect bounds, Map paintServers) { - final rawFill = getAttribute(el, 'fill'); - if (rawFill == '') { +Paint parseFill(XmlElement el, Rect bounds, + Map paintServers, Color defaultFillIfNotSpecified) { + final String rawFill = getAttribute(el, 'fill', def: null); + if (rawFill == null) { + if (defaultFillIfNotSpecified == null) { + return null; + } + return new Paint()..color = defaultFillIfNotSpecified; + } + if (rawFill == 'none') { return null; } @@ -222,15 +241,12 @@ Paint parseFill( return paintServers[rawFill](bounds); } - var rawOpacity = getAttribute(el, 'fill-opacity'); - if (rawOpacity == '') { - rawOpacity = getAttribute(el, 'opacity'); - } - final opacity = rawOpacity == '' + final String rawOpacity = getAttribute(el, 'fill-opacity'); + final double opacity = rawOpacity == '' ? rawFill == 'none' ? 0.0 : 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); - final fill = parseColor(rawFill).withOpacity(opacity); + final Color fill = parseColor(rawFill).withOpacity(opacity); return new Paint() ..color = fill @@ -241,4 +257,3 @@ PathFillType parseFillRule(XmlElement el) { final String rawFillRule = getAttribute(el, 'fill-rule', def: 'nonzero'); return parseRawFillRule(rawFillRule); } - diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 0218478dbebe..b24fcf372954 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -10,24 +10,31 @@ import 'svg/parsers.dart'; import 'svg/xml_parsers.dart'; import 'utilities/xml.dart'; -typedef DrawableSvgShape SvgShapeFactory( - XmlElement el, Map paintServers); +typedef DrawableSvgShape SvgShapeFactory(XmlElement el, + Map paintServers, DrawableStyle parentStyle); final Map _shapes = { - 'circle': (XmlElement el, Map paintServers) => - new DrawableSvgShape.fromSvgCircle(el, paintServers), - 'path': (XmlElement el, Map paintServers) => - new DrawableSvgShape.fromSvgPath(el, paintServers), - 'rect': (XmlElement el, Map paintServers) => - new DrawableSvgShape.fromSvgRect(el, paintServers), - 'polygon': (XmlElement el, Map paintServers) => - new DrawableSvgShape.fromSvgPolygonOrLine(el, paintServers), - 'polyline': (XmlElement el, Map paintServers) => - new DrawableSvgShape.fromSvgPolygonOrLine(el, paintServers), - 'ellipse': (XmlElement el, Map paintServers) => - new DrawableSvgShape.fromSvgEllipse(el, paintServers), - 'line': (XmlElement el, Map paintServers) => - new DrawableSvgShape.fromSvgLine(el, paintServers), + 'circle': (XmlElement el, Map paintServers, + DrawableStyle parentStyle) => + new DrawableSvgShape.fromSvgCircle(el, paintServers, parentStyle), + 'path': (XmlElement el, Map paintServers, + DrawableStyle parentStyle) => + new DrawableSvgShape.fromSvgPath(el, paintServers, parentStyle), + 'rect': (XmlElement el, Map paintServers, + DrawableStyle parentStyle) => + new DrawableSvgShape.fromSvgRect(el, paintServers, parentStyle), + 'polygon': (XmlElement el, Map paintServers, + DrawableStyle parentStyle) => + new DrawableSvgShape.fromSvgPolygonOrLine(el, paintServers, parentStyle), + 'polyline': (XmlElement el, Map paintServers, + DrawableStyle parentStyle) => + new DrawableSvgShape.fromSvgPolygonOrLine(el, paintServers, parentStyle), + 'ellipse': (XmlElement el, Map paintServers, + DrawableStyle parentStyle) => + new DrawableSvgShape.fromSvgEllipse(el, paintServers, parentStyle), + 'line': (XmlElement el, Map paintServers, + DrawableStyle parentStyle) => + new DrawableSvgShape.fromSvgLine(el, paintServers, parentStyle), }; /// An SVG Shape element that will be drawn to the canvas. @@ -49,39 +56,43 @@ class DrawableSvgShape extends DrawableShape { } } - static _createDrawable( - Path path, Map paintServers, XmlElement el) { + static _createDrawable(Path path, Map paintServers, + XmlElement el, DrawableStyle parentStyle) { assert(path != null); + final Color defaultFill = parentStyle?.fill != null ? null : colorBlack; + return new DrawableSvgShape( transformPath(path, el), - parseStyle(el, paintServers, path.getBounds()), + parseStyle(el, paintServers, path.getBounds(), + defaultFillIfNotSpecified: defaultFill), ); } /// Creates a [DrawableSvgShape] from an SVG element. - factory DrawableSvgShape.fromSvgCircle( - XmlElement el, Map paintServers) { + factory DrawableSvgShape.fromSvgCircle(XmlElement el, + Map paintServers, DrawableStyle parentStyle) { final cx = double.parse(getAttribute(el, 'cx', def: '0')); final cy = double.parse(getAttribute(el, 'cy', def: '0')); final r = double.parse(getAttribute(el, 'r', def: '0')); final oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); final path = new Path()..addOval(oval); - return _createDrawable(path, paintServers, el); + return _createDrawable(path, paintServers, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG element. - factory DrawableSvgShape.fromSvgPath( - XmlElement el, Map paintServers) { + factory DrawableSvgShape.fromSvgPath(XmlElement el, + Map paintServers, DrawableStyle parentStyle) { final d = getAttribute(el, 'd'); final Path path = parseSvgPathData(d); - return _createDrawable(path, paintServers, el); + + return _createDrawable(path, paintServers, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG element. - factory DrawableSvgShape.fromSvgRect( - XmlElement el, Map paintServers) { + factory DrawableSvgShape.fromSvgRect(XmlElement el, + Map paintServers, DrawableStyle parentStyle) { final double x = double.parse(getAttribute(el, 'x', def: '0')); final double y = double.parse(getAttribute(el, 'y', def: '0')); final double w = double.parse(getAttribute(el, 'width', def: '0')); @@ -100,28 +111,29 @@ class DrawableSvgShape extends DrawableShape { new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)), paintServers, el, + parentStyle, ); } final path = new Path()..addRect(rect); - return _createDrawable(path, paintServers, el); + return _createDrawable(path, paintServers, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG or element. - factory DrawableSvgShape.fromSvgPolygonOrLine( - XmlElement el, Map paintServers) { + factory DrawableSvgShape.fromSvgPolygonOrLine(XmlElement el, + Map paintServers, DrawableStyle parentStyle) { final points = getAttribute(el, 'points'); if (points == '') { - return _createDrawable(null, paintServers, el); + return _createDrawable(null, paintServers, el, parentStyle); } final path = parseSvgPathData('M' + points + 'z'); - return _createDrawable(path, paintServers, el); + return _createDrawable(path, paintServers, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG element. - factory DrawableSvgShape.fromSvgEllipse( - XmlElement el, Map paintServers) { + factory DrawableSvgShape.fromSvgEllipse(XmlElement el, + Map paintServers, DrawableStyle parentStyle) { final cx = double.parse(getAttribute(el, 'cx', def: '0')); final cy = double.parse(getAttribute(el, 'cy', def: '0')); final rx = double.parse(getAttribute(el, 'rx', def: '0')); @@ -129,12 +141,13 @@ class DrawableSvgShape extends DrawableShape { Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); - return _createDrawable(new Path()..addOval(r), paintServers, el); + return _createDrawable( + new Path()..addOval(r), paintServers, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG element. - factory DrawableSvgShape.fromSvgLine( - XmlElement el, Map paintServers) { + factory DrawableSvgShape.fromSvgLine(XmlElement el, + Map paintServers, DrawableStyle parentStyle) { final x1 = double.parse(getAttribute(el, 'x1', def: '0')); final x2 = double.parse(getAttribute(el, 'x2', def: '0')); final y1 = double.parse(getAttribute(el, 'y1', def: '0')); @@ -143,20 +156,25 @@ class DrawableSvgShape extends DrawableShape { final path = new Path() ..moveTo(x1, y1) ..lineTo(x2, y2); - return _createDrawable(path, paintServers, el); + return _createDrawable(path, paintServers, el, parentStyle); } } /// Creates a [Drawable] from an SVG or shape element. Also handles parsing and gradients. /// /// If an unsupported element is encountered, it will be created as a [DrawableNoop]. -Drawable parseSvgElement( - XmlElement el, Map paintServers, Rect bounds) { +Drawable parseSvgElement(XmlElement el, Map paintServers, + Rect bounds, DrawableStyle parentStyle) { final SvgShapeFactory shapeFn = _shapes[el.name.local]; if (shapeFn != null) { - return shapeFn(el, paintServers); + return shapeFn(el, paintServers, parentStyle); } else if (el.name.local == 'defs') { parseDefs(el, paintServers); + return new DrawableNoop(el.name.local); + } else if (el.name.local.endsWith('Gradient')) { + paintServers['url(#${getAttribute(el, 'id')})'] = + (Rect bounds) => parseGradient(el, bounds); + return new DrawableNoop(el.name.local); } else if (el.name.local == 'g' || el.name.local == 'a') { return parseSvgGroup(el, paintServers, bounds); } else if (el.name.local == 'text') { @@ -174,10 +192,12 @@ Drawable parseSvgText( final Offset offset = new Offset( double.parse(getAttribute(el, 'x', def: '0')), double.parse(getAttribute(el, 'y', def: '0'))); + return new DrawableText( el.text, offset, new DrawableStyle( + groupOpacity: parseOpacity(el), textStyle: new TextStyle( fontFamily: getAttribute(el, 'font-family'), fontSize: double.parse(getAttribute(el, 'font-size', def: '55')), @@ -198,9 +218,11 @@ Drawable parseSvgText( Drawable parseSvgGroup( XmlElement el, Map paintServers, Rect bounds) { final List children = []; + final DrawableStyle style = + parseStyle(el, paintServers, bounds, needsTransform: true); el.children.forEach((child) { if (child is XmlElement) { - final Drawable el = parseSvgElement(child, paintServers, bounds); + final Drawable el = parseSvgElement(child, paintServers, bounds, style); if (el != null) { children.add(el); } @@ -213,7 +235,7 @@ Drawable parseSvgGroup( // el.children // .whereType() // .map((child) => new SvgBaseElement.fromXml(child)), - parseStyle(el, paintServers, bounds, needsTransform: true)); + style); } /// Parses style attributes or @style attribute. @@ -221,18 +243,17 @@ Drawable parseSvgGroup( /// Remember that @style attribute takes precedence. DrawableStyle parseStyle( XmlElement el, Map paintServers, Rect bounds, - {bool needsTransform = false}) { + {bool needsTransform = false, Color defaultFillIfNotSpecified}) { final Matrix4 transform = needsTransform ? parseTransform(getAttribute(el, 'transform')) : null; - final Paint fill = parseFill(el, bounds, paintServers); - final Paint stroke = parseStroke(el, bounds, paintServers); return new DrawableStyle( transform: transform?.storage, - stroke: stroke, + stroke: parseStroke(el, bounds, paintServers), dashArray: parseDashArray(el), dashOffset: parseDashOffset(el), - fill: fill, + fill: parseFill(el, bounds, paintServers, defaultFillIfNotSpecified), pathFillType: parseFillRule(el), + groupOpacity: parseOpacity(el), ); } diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 7fa3378bd497..e7e6183de7f8 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -27,6 +27,7 @@ class DrawableStyle { final Float64List transform; final TextStyle textStyle; final PathFillType pathFillType; + final double groupOpacity; const DrawableStyle( {this.stroke, @@ -35,16 +36,17 @@ class DrawableStyle { this.fill, this.transform, this.textStyle, - this.pathFillType}); + this.pathFillType, + this.groupOpacity}); /// Creates a new [DrawableStyle] if `other` is not null, filling in any null properties on /// this with the properties from other. /// /// If `other` is null, returns this. - DrawableStyle merge(DrawableStyle other) { + DrawableStyle mergeAndBlend(DrawableStyle other) { if (other == null) return this; - return new DrawableStyle( + final DrawableStyle ret = new DrawableStyle( fill: this.fill ?? other.fill, stroke: this.stroke ?? other.stroke, dashArray: this.dashArray ?? other.dashArray, @@ -52,7 +54,34 @@ class DrawableStyle { transform: this.transform ?? other.transform, textStyle: this.textStyle ?? other.textStyle, pathFillType: this.pathFillType ?? other.pathFillType, + groupOpacity: mergeOpacity(this.groupOpacity, other.groupOpacity), ); + + if (ret.fill != null) { + // print( + // 'before ${ret.fill.color} ${ret.groupOpacity} ${ret.fill.color.opacity} ${mergeOpacity(ret.fill.color.opacity, ret.groupOpacity)}'); + ret.fill.color = ret.fill.color.withOpacity(ret.fill.color.opacity == 1.0 + ? ret.groupOpacity ?? 1.0 + : mergeOpacity(ret.groupOpacity, ret.fill.color.opacity)); + } + if (ret.stroke != null) { + ret.stroke.color = ret.stroke.color.withOpacity( + ret.stroke.color.opacity == 1.0 + ? ret.groupOpacity ?? 1.0 + : mergeOpacity(ret.groupOpacity, ret.stroke.color.opacity)); + } + + return ret; + } + + static double mergeOpacity(double back, double front) { + if (back == null) { + return front; + } else if (front == null) { + return back; + } + return (front + back) / 2.0; + //return back + (1.0 - back) * front; } } @@ -132,7 +161,7 @@ class DrawableRoot implements Drawable { @override void draw(Canvas canvas, [DrawableStyle parentStyle]) { children.forEach((child) => - child.draw(canvas, style?.merge(parentStyle) ?? parentStyle)); + child.draw(canvas, style?.mergeAndBlend(parentStyle) ?? parentStyle)); } } @@ -165,7 +194,7 @@ class DrawableGroup implements Drawable { canvas.transform(style?.transform); } children.forEach((child) { - child.draw(canvas, style?.merge(parentStyle) ?? parentStyle); + child.draw(canvas, style?.mergeAndBlend(parentStyle) ?? parentStyle); }); if (style?.transform != null) { canvas.restore(); @@ -177,7 +206,6 @@ class DrawableGroup implements Drawable { class DrawableShape implements Drawable { final DrawableStyle style; final Path path; - static final Paint _blackPaint = new Paint()..color = const Color(0xFF000000); Rect get bounds => path?.getBounds(); @@ -189,15 +217,13 @@ class DrawableShape implements Drawable { @override void draw(Canvas canvas, [DrawableStyle parentStyle]) { - final DrawableStyle localStyle = style.merge(parentStyle); - + final DrawableStyle localStyle = style.mergeAndBlend(parentStyle); path.fillType = localStyle.pathFillType ?? PathFillType.nonZero; if (localStyle?.fill != null) { canvas.drawPath(path, localStyle.fill); - } else { - canvas.drawPath(path, _blackPaint); } + if (localStyle?.stroke != null) { if (localStyle.dashArray != null) { canvas.drawPath( diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 53cedfcc824a..dc13fe94e19c 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -69,13 +69,21 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { final XmlElement svg = xml.parse(rawSvg).rootElement; final Rect viewBox = parseViewBox(svg); Map paintServers = {}; + final DrawableStyle style = parseStyle(svg, paintServers, viewBox); + final List children = svg.children .where((XmlNode child) => child is XmlElement) - .map((XmlNode child) => parseSvgElement( - child, - paintServers, - new Rect.fromPoints( - Offset.zero, new Offset(size.width, size.height)))) + .map( + (XmlNode child) => parseSvgElement( + child, + paintServers, + new Rect.fromPoints( + Offset.zero, + new Offset(size.width, size.height), + ), + style, + ), + ) .toList(); return new DrawableRoot( viewBox, diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 3a4d8d0ec7b1..00ab9da67f8d 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -7,28 +7,21 @@ packages: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.31.1" + version: "0.31.2-alpha.2" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.4.2" + version: "1.4.3" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.0.6" - barback: - dependency: transitive - description: - name: barback - url: "https://pub.dartlang.org" - source: hosted - version: "0.15.2+15" + version: "2.0.7" boolean_selector: dependency: transitive description: @@ -43,13 +36,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" - cli_util: - dependency: transitive - description: - name: cli_util - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+1" collection: dependency: transitive description: @@ -70,14 +56,14 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.0.2+1" + version: "2.0.3" csslib: dependency: transitive description: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.14.1" + version: "0.14.3" cupertino_icons: dependency: "direct main" description: @@ -101,7 +87,7 @@ packages: name: front_end url: "https://pub.dartlang.org" source: hosted - version: "0.1.0-alpha.9" + version: "0.1.0-alpha.12" glob: dependency: transitive description: @@ -136,7 +122,7 @@ packages: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.1" + version: "3.1.2" io: dependency: transitive description: @@ -144,13 +130,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.2+1" - isolate: - dependency: transitive - description: - name: isolate - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" js: dependency: transitive description: @@ -164,7 +143,7 @@ packages: name: kernel url: "https://pub.dartlang.org" source: hosted - version: "0.3.0-alpha.9" + version: "0.3.0-alpha.12" logging: dependency: transitive description: @@ -178,14 +157,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.1+4" + version: "0.12.2+1" meta: dependency: "direct main" description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.1.5" mime: dependency: transitive description: @@ -206,7 +185,7 @@ packages: name: node_preamble url: "https://pub.dartlang.org" source: hosted - version: "1.4.0" + version: "1.4.1" package_config: dependency: transitive description: @@ -262,7 +241,7 @@ packages: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.3.6" + version: "1.4.1" quiver: dependency: transitive description: @@ -276,7 +255,7 @@ packages: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "0.7.2" + version: "0.7.3" shelf_packages_handler: dependency: transitive description: @@ -316,7 +295,7 @@ packages: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.4" + version: "0.10.5" source_span: dependency: transitive description: @@ -337,7 +316,7 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" + version: "1.6.6" string_scanner: dependency: transitive description: @@ -358,7 +337,7 @@ packages: name: test url: "https://pub.dartlang.org" source: hosted - version: "0.12.34" + version: "0.12.37" typed_data: dependency: transitive description: @@ -409,5 +388,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.c080951d45e79cd25df98036c4be835b284a269c" + dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.54.0.flutter-779dc6eb85" flutter: ">=0.3.6 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index a0cd62b58853..aa857041fdda 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -36,6 +36,7 @@ flutter: # To add assets to your application, add an assets section, like this: assets: - assets/flutter_logo.svg + - assets/dart.svg - assets/w3samples/alphachannel.svg - assets/w3samples/aa.svg - assets/deborah_ufw/new-action-expander.svg @@ -49,6 +50,7 @@ flutter: - assets/deborah_ufw/new-send-circle.svg - assets/deborah_ufw/numeric_25.svg - assets/simple/ellipse.svg + - assets/simple/group_opacity.svg - assets/simple/nested_group.svg - assets/simple/rect_rrect.svg - assets/simple/linear_gradient.svg From 00ec89f2c55d954d9511dfd04750cae2470b1a72 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 11 May 2018 00:48:08 -0400 Subject: [PATCH 046/512] uncomment code --- third_party/example/main.dart | 4 +-- third_party/pubspec.lock | 49 +++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index d25f67f2835e..eb61f4bdc315 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -86,8 +86,8 @@ class _MyHomePageState extends State { ), ); }); - // _painters.add(new AvdImage.asset('assets/android_vd/battery_charging.xml', - // new Size(_dimension, _dimension))); + _painters.add(new AvdImage.asset('assets/android_vd/battery_charging.xml', + new Size(_dimension, _dimension))); } @override diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 00ab9da67f8d..1be32dc60336 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -14,14 +14,21 @@ packages: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.4.3" + version: "1.4.2" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.0.7" + version: "2.0.6" + barback: + dependency: transitive + description: + name: barback + url: "https://pub.dartlang.org" + source: hosted + version: "0.15.2+15" boolean_selector: dependency: transitive description: @@ -36,6 +43,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2+1" collection: dependency: transitive description: @@ -56,14 +70,14 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.2+1" csslib: dependency: transitive description: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.14.3" + version: "0.14.1" cupertino_icons: dependency: "direct main" description: @@ -122,7 +136,7 @@ packages: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.2" + version: "3.1.1" io: dependency: transitive description: @@ -130,6 +144,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.2+1" + isolate: + dependency: transitive + description: + name: isolate + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0" js: dependency: transitive description: @@ -157,14 +178,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.2+1" + version: "0.12.1+4" meta: dependency: "direct main" description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.5" + version: "1.1.2" mime: dependency: transitive description: @@ -185,7 +206,7 @@ packages: name: node_preamble url: "https://pub.dartlang.org" source: hosted - version: "1.4.1" + version: "1.4.0" package_config: dependency: transitive description: @@ -241,7 +262,7 @@ packages: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.4.1" + version: "1.3.6" quiver: dependency: transitive description: @@ -255,7 +276,7 @@ packages: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "0.7.3" + version: "0.7.2" shelf_packages_handler: dependency: transitive description: @@ -295,7 +316,7 @@ packages: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.5" + version: "0.10.4" source_span: dependency: transitive description: @@ -316,7 +337,7 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "1.6.6" + version: "1.6.4" string_scanner: dependency: transitive description: @@ -337,7 +358,7 @@ packages: name: test url: "https://pub.dartlang.org" source: hosted - version: "0.12.37" + version: "0.12.34" typed_data: dependency: transitive description: @@ -388,5 +409,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.54.0.flutter-779dc6eb85" + dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.c080951d45e79cd25df98036c4be835b284a269c" flutter: ">=0.3.6 <2.0.0" From 14002bf10e1c58dc7a3b85e3b644276df73ddb6e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 11 May 2018 01:08:55 -0400 Subject: [PATCH 047/512] update docs --- third_party/CHANGELOG.md | 11 +++++++++-- third_party/flutter_svg.iml | 1 + third_party/flutter_svg_android.iml | 3 ++- third_party/pubspec.yaml | 2 +- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 9b545536267f..6e76a74cd8dc 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGES +## 0.1.1 + +- Handle opacity on groups and inherited/blended opacity. +- Fixes elements that have both opacity and stroke-opacity or fill-opacity. +- Improvements for inheritence. +- Fixes related to unspecified fills on shapes. + ## 0.1.0 Bumping minor version due to internal breaking changes and new support. Works on dev channel as of release (Flutter >= 0.3.6). @@ -13,8 +20,8 @@ Bumping minor version due to internal breaking changes and new support. Works on ## 0.0.2 -Initial text support. Relies on flutter 0.3.6 +Initial text support. Relies on flutter 0.3.6. ## 0.0.1 -Initial release. Relies on pre-released master +Initial release. Relies on pre-released master. diff --git a/third_party/flutter_svg.iml b/third_party/flutter_svg.iml index 485a35d430c6..e5c837191e06 100644 --- a/third_party/flutter_svg.iml +++ b/third_party/flutter_svg.iml @@ -5,6 +5,7 @@ + diff --git a/third_party/flutter_svg_android.iml b/third_party/flutter_svg_android.iml index 0ca70ed93eaf..57406edb174c 100644 --- a/third_party/flutter_svg_android.iml +++ b/third_party/flutter_svg_android.iml @@ -3,6 +3,7 @@ + - + \ No newline at end of file diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index aa857041fdda..71aa1b5d36f0 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.1.0 +version: 0.1.1 dependencies: path_drawing: ^0.2.2 From 3b7a2e7db837c0bc51a49ac80acb5dd44d6ee3f5 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 11 May 2018 01:43:27 -0400 Subject: [PATCH 048/512] stricter analysis options --- third_party/example/main.dart | 24 ++--- third_party/lib/avd.dart | 12 +-- third_party/lib/src/avd/xml_parsers.dart | 16 ++-- third_party/lib/src/avd_parser.dart | 12 +-- third_party/lib/src/svg/colors.dart | 14 +-- third_party/lib/src/svg/parsers.dart | 42 ++++----- third_party/lib/src/svg/xml_parsers.dart | 34 +++---- third_party/lib/src/svg_parser.dart | 108 ++++++++++++----------- third_party/lib/src/utilities/xml.dart | 2 +- third_party/lib/src/vector_painter.dart | 49 +++++----- third_party/lib/svg.dart | 14 +-- third_party/lib/vector_drawable.dart | 9 +- third_party/test/xml_test.dart | 8 +- 13 files changed, 178 insertions(+), 166 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index eb61f4bdc315..528f81567aa1 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -3,7 +3,7 @@ import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/vector_drawable.dart'; import 'package:flutter_svg/svg.dart'; -const List assetNames = const [ +const List assetNames = const [ 'assets/flutter_logo.svg', 'assets/dart.svg', 'assets/simple/group_opacity.svg', @@ -31,7 +31,7 @@ const List assetNames = const [ 'assets/wikimedia/Ghostscript_Tiger.svg', ]; -const List uriNames = const [ +const List uriNames = const [ 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', ]; @@ -47,13 +47,13 @@ class MyApp extends StatelessWidget { theme: new ThemeData( primarySwatch: Colors.blue, ), - home: new MyHomePage(title: 'Flutter SVG Demo'), + home: const MyHomePage(title: 'Flutter SVG Demo'), ); } } class MyHomePage extends StatefulWidget { - MyHomePage({Key key, this.title}) : super(key: key); + const MyHomePage({Key key, this.title}) : super(key: key); final String title; @override @@ -61,7 +61,7 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - List _painters = new List(); + final List _painters = []; double _dimension; @override @@ -69,23 +69,23 @@ class _MyHomePageState extends State { super.initState(); _dimension = 365.0; - assetNames.forEach((assetName) { + for (String assetName in assetNames) { _painters.add( new SvgImage.asset( assetName, new Size(_dimension, _dimension), ), ); - }); + } - uriNames.forEach((uri) { + for (String uriName in uriNames) { _painters.add( new SvgImage.network( - uri, + uriName, new Size(_dimension, _dimension), ), ); - }); + } _painters.add(new AvdImage.asset('assets/android_vd/battery_charging.xml', new Size(_dimension, _dimension))); } @@ -99,12 +99,12 @@ class _MyHomePageState extends State { appBar: new AppBar( title: new Text(widget.title), ), - body: new Column(children: [ + body: new Column(children: [ new Slider( min: 5.0, max: MediaQuery.of(context).size.width - 10.0, value: _dimension, - onChanged: (val) { + onChanged: (double val) { setState(() => _dimension = val); }), // new FlutterLogo(size: _dimension), diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 193a62bbe4dd..106342527ac7 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -1,20 +1,20 @@ import 'dart:async'; -import 'dart:io'; import 'dart:convert'; +import 'dart:io'; import 'package:flutter/services.dart' show rootBundle, AssetBundle; import 'package:flutter/widgets.dart'; import 'package:xml/xml.dart' hide parse; import 'package:xml/xml.dart' as xml show parse; -import 'vector_drawable.dart'; -import 'src/vector_painter.dart'; -import 'src/avd_parser.dart'; import 'src/avd/xml_parsers.dart'; +import 'src/avd_parser.dart'; +import 'src/vector_painter.dart'; +import 'vector_drawable.dart'; /// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. class AvdImage extends VectorDrawableImage { - AvdImage._(Future future, Size size, + const AvdImage._(Future future, Size size, {bool clipToViewBox, Key key, PaintLocation paintLocation}) : super(future, size, clipToViewBox: clipToViewBox, @@ -26,7 +26,7 @@ class AvdImage extends VectorDrawableImage { bool clipToViewBox = true, PaintLocation paintLocation = PaintLocation.Background}) { return new AvdImage._( - new Future.value(fromAvdString(svg, size)), + new Future.value(fromAvdString(svg, size)), size, clipToViewBox: clipToViewBox, key: key, diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index 0bdae0f6c947..0386e526bd3e 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -4,8 +4,8 @@ import 'dart:ui'; import 'package:vector_math/vector_math_64.dart'; import 'package:xml/xml.dart'; -import '../utilities/xml.dart'; import '../svg/colors.dart'; +import '../utilities/xml.dart'; const String androidNS = 'http://schemas.android.com/apk/res/android'; @@ -24,19 +24,19 @@ Rect parseViewBox(XmlElement el) { } Matrix4 parseTransform(XmlElement el) { - double rotation = double + final double rotation = double .parse(getAttribute(el, 'rotation', def: '0', namespace: androidNS)); - double pivotX = + final double pivotX = double.parse(getAttribute(el, 'pivotX', def: '0', namespace: androidNS)); - double pivotY = + final double pivotY = double.parse(getAttribute(el, 'pivotY', def: '0', namespace: androidNS)); - double scaleX = + final double scaleX = double.parse(getAttribute(el, 'scaleX', def: '1', namespace: androidNS)); - double scaleY = + final double scaleY = double.parse(getAttribute(el, 'scaleY', def: '1', namespace: androidNS)); - double translateX = double + final double translateX = double .parse(getAttribute(el, 'translateX', def: '0', namespace: androidNS)); - double translateY = double + final double translateY = double .parse(getAttribute(el, 'translateY', def: '0', namespace: androidNS)); return new Matrix4.identity() diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index e5f80347931c..3f355b29b136 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -4,9 +4,9 @@ import 'package:xml/xml.dart'; import 'package:path_drawing/path_drawing.dart'; import 'package:vector_math/vector_math_64.dart'; -import 'vector_painter.dart'; import 'avd/xml_parsers.dart'; import 'utilities/xml.dart'; +import 'vector_painter.dart'; class DrawableAvdRoot extends DrawableRoot { const DrawableAvdRoot(Rect viewBox, List children, @@ -20,13 +20,13 @@ class DrawableAvdPath extends DrawableShape { /// Creates a [DrawableAvdPath] from an XML element factory DrawableAvdPath.fromXml(XmlElement el) { - final d = getAttribute(el, 'pathData', def: '', namespace: androidNS); + final String d = getAttribute(el, 'pathData', def: '', namespace: androidNS); final Path path = parseSvgPathData(d); assert(path != null); path.fillType = parsePathFillType(el); - final stroke = parseStroke(el, path.getBounds()); - final fill = parseFill(el, path.getBounds()); + final Paint stroke = parseStroke(el, path.getBounds()); + final Paint fill = parseFill(el, path.getBounds()); return new DrawableAvdPath( path, @@ -52,14 +52,14 @@ Drawable parseAvdElement(XmlElement el, Rect bounds) { /// Parses an AVD element. Drawable parseAvdGroup(XmlElement el, Rect bounds) { final List children = []; - el.children.forEach((child) { + for (XmlNode child in el.children) { if (child is XmlElement) { final Drawable el = parseAvdElement(child, bounds); if (el != null) { children.add(el); } } - }); + } final Matrix4 transform = parseTransform(el); diff --git a/third_party/lib/src/svg/colors.dart b/third_party/lib/src/svg/colors.dart index b3be7bd8b226..2ea10f1895db 100644 --- a/third_party/lib/src/svg/colors.dart +++ b/third_party/lib/src/svg/colors.dart @@ -1,10 +1,10 @@ import 'dart:ui'; -const colorBlack = const Color(0xFF000000); +const Color colorBlack = const Color(0xFF000000); /// Converts a SVG Color String (either a # prefixed color string or a named color) to a [Color]. Color parseColor(String colorString) { - if (colorString == null || colorString.length == 0) { + if (colorString == null || colorString.isEmpty) { return colorBlack; } @@ -15,9 +15,9 @@ Color parseColor(String colorString) { // handle hex colors e.g. #fff or #ffffff. This supports #RRGGBBAA if (colorString[0] == '#') { if (colorString.length == 4) { - final r = colorString[1]; - final g = colorString[2]; - final b = colorString[3]; + final String r = colorString[1]; + final String g = colorString[2]; + final String b = colorString[3]; colorString = '#$r$r$g$g$b$b'; } int color = int.parse(colorString.substring(1), radix: 16); @@ -53,7 +53,7 @@ Color parseColor(String colorString) { } // handle named colors ('red', 'green', etc.). - final namedColor = _namedColors[colorString]; + final Color namedColor = _namedColors[colorString]; if (namedColor != null) { return namedColor; } @@ -63,7 +63,7 @@ Color parseColor(String colorString) { } // https://www.w3.org/TR/SVG11/types.html#ColorKeywords -const Map _namedColors = const { +const Map _namedColors = const { 'aliceblue': const Color.fromARGB(255, 240, 248, 255), 'antiquewhite': const Color.fromARGB(255, 250, 235, 215), 'aqua': const Color.fromARGB(255, 0, 255, 255), diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index ad10ec48fc71..d0864c122be9 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -9,7 +9,7 @@ final RegExp _transformCommand = new RegExp(_transformCommandAtom); typedef Matrix4 MatrixParser(String paramsStr, Matrix4 current); -const Map _matrixParsers = const { +const Map _matrixParsers = const { 'matrix': _parseSvgMatrix, 'translate': _parseSvgTranslate, 'scale': _parseSvgScale, @@ -36,7 +36,7 @@ Matrix4 parseTransform(String transform) { final String command = m.group(1); final String params = m.group(2); - final transformer = _matrixParsers[command]; + final MatrixParser transformer = _matrixParsers[command]; if (transformer == null) { throw new FormatException('Unsupported transform: $command'); } @@ -49,27 +49,27 @@ Matrix4 parseTransform(String transform) { final RegExp _valueSeparator = new RegExp('( *, *| +)'); Matrix4 _parseSvgMatrix(String paramsStr, Matrix4 current) { - final params = paramsStr.split(_valueSeparator); + final List params = paramsStr.split(_valueSeparator); assert(params.isNotEmpty); assert(params.length == 6); - final a = double.parse(params[0]); - final b = double.parse(params[1]); - final c = double.parse(params[2]); - final d = double.parse(params[3]); - final e = double.parse(params[4]); - final f = double.parse(params[5]); - - return _matrix(a, b, c, d, e, f).multiplied(current); + final double a = double.parse(params[0]); + final double b = double.parse(params[1]); + final double c = double.parse(params[2]); + final double d = double.parse(params[3]); + final double e = double.parse(params[4]); + final double f = double.parse(params[5]); + + return _affineMatrix(a, b, c, d, e, f).multiplied(current); } Matrix4 _parseSvgSkewX(String paramsStr, Matrix4 current) { - final x = double.parse(paramsStr); - return _matrix(1.0, tan(x), 0.0, 0.0, 1.0, 0.0).multiplied(current); + final double x = double.parse(paramsStr); + return _affineMatrix(1.0, tan(x), 0.0, 0.0, 1.0, 0.0).multiplied(current); } Matrix4 _parseSvgSkewY(String paramsStr, Matrix4 current) { - final y = double.parse(paramsStr); - return _matrix(1.0, 0.0, 0.0, tan(y), 1.0, 0.0).multiplied(current); + final double y = double.parse(paramsStr); + return _affineMatrix(1.0, 0.0, 0.0, tan(y), 1.0, 0.0).multiplied(current); } Matrix4 _parseSvgTranslate(String paramsStr, Matrix4 current) { @@ -78,7 +78,7 @@ Matrix4 _parseSvgTranslate(String paramsStr, Matrix4 current) { assert(params.length <= 2); final double x = double.parse(params[0]); final double y = params.length < 2 ? x : double.parse(params[1]); - return _matrix(1.0, 0.0, 0.0, 1.0, x, y).multiplied(current); + return _affineMatrix(1.0, 0.0, 0.0, 1.0, x, y).multiplied(current); } Matrix4 _parseSvgScale(String paramsStr, Matrix4 current) { @@ -87,7 +87,7 @@ Matrix4 _parseSvgScale(String paramsStr, Matrix4 current) { assert(params.length <= 2); final double x = double.parse(params[0]); final double y = params.length < 2 ? x : double.parse(params[1]); - return _matrix(x, 0.0, 0.0, y, 0.0, 0.0).multiplied(current); + return _affineMatrix(x, 0.0, 0.0, y, 0.0, 0.0).multiplied(current); } Matrix4 _parseSvgRotate(String paramsStr, Matrix4 current) { @@ -95,21 +95,21 @@ Matrix4 _parseSvgRotate(String paramsStr, Matrix4 current) { assert(params.length <= 3); final double a = radians(double.parse(params[0])); - final rotate = _matrix(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0); + final Matrix4 rotate = _affineMatrix(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0); if (params.length > 1) { final double x = double.parse(params[1]); final double y = params.length == 3 ? double.parse(params[2]) : x; - return _matrix(1.0, 0.0, 0.0, 1.0, x, y) + return _affineMatrix(1.0, 0.0, 0.0, 1.0, x, y) .multiplied(current) .multiplied(rotate) - .multiplied(_matrix(1.0, 0.0, 0.0, 1.0, -x, -y)); + .multiplied(_affineMatrix(1.0, 0.0, 0.0, 1.0, -x, -y)); } else { return rotate.multiplied(current); } } -Matrix4 _matrix(double a, double b, double c, double d, double e, double f) { +Matrix4 _affineMatrix(double a, double b, double c, double d, double e, double f) { return new Matrix4( a, b, 0.0, 0.0, c, d, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, e, f, 0.0, 1.0); } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index f95dd6c30cb5..339fa02601bb 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -3,8 +3,8 @@ import 'dart:ui'; import 'package:path_drawing/path_drawing.dart'; import 'package:xml/xml.dart'; -import '../vector_painter.dart'; import '../utilities/xml.dart'; +import '../vector_painter.dart'; import 'colors.dart'; import 'parsers.dart'; @@ -26,7 +26,7 @@ Rect parseViewBox(XmlElement svg) { return new Rect.fromLTWH(0.0, 0.0, width, height); } - final parts = viewBox.split(new RegExp(r'[ ,]+')); + final List parts = viewBox.split(new RegExp(r'[ ,]+')); if (parts.length < 4) { throw new StateError('viewBox element must be 4 elements long'); } @@ -40,14 +40,14 @@ Rect parseViewBox(XmlElement svg) { /// Parses a element, extracting and (TODO) elements into the `paintServers` map. void parseDefs(XmlElement el, Map paintServers) { - el.children.forEach((XmlNode def) { + for (XmlNode def in el.children) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { paintServers['url(#${getAttribute(def, 'id')})'] = (Rect bounds) => parseGradient(def, bounds); } } - }); + } } double _parseDecimalOrPercentage(String val) { @@ -78,16 +78,16 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { bounds.left + (bounds.height * y2), ); - final stops = el.findElements('stop').toList(); + final List stops = el.findElements('stop').toList(); final Gradient gradient = new Gradient.linear( from, to, - stops.map((stop) { + stops.map((XmlElement stop) { final String rawOpacity = getAttribute(stop, 'stop-opacity', def: '1'); return parseColor(getAttribute(stop, 'stop-color')) .withOpacity(double.parse(rawOpacity)); }).toList(), - stops.map((stop) { + stops.map((XmlElement stop) { final String rawOffset = getAttribute(stop, 'offset'); return _parseDecimalOrPercentage(rawOffset); }).toList(), @@ -113,16 +113,16 @@ Paint parseRadialGradient(XmlElement el, Rect bounds) { 'Focal points not supported by this implementation'); } - final stops = el.findElements('stop').toList(); + final List stops = el.findElements('stop').toList(); final Gradient gradient = new Gradient.radial( new Offset(cx, cy), r, - stops.map((stop) { + stops.map((XmlElement stop) { final String rawOpacity = getAttribute(stop, 'stop-opacity', def: '1'); return parseColor(getAttribute(stop, 'stop-color')) .withOpacity(double.parse(rawOpacity)); }).toList(), - stops.map((stop) { + stops.map((XmlElement stop) { final String rawOffset = getAttribute(stop, 'offset'); return _parseDecimalOrPercentage(rawOffset); }).toList(), @@ -151,13 +151,13 @@ CircularIntervalList parseDashArray(XmlElement el) { } final List parts = rawDashArray.split(new RegExp(r'[ ,]+')); - return new CircularIntervalList( - parts.map((part) => double.parse(part)).toList()); + return new CircularIntervalList( + parts.map((String part) => double.parse(part)).toList()); } /// Parses a @stroke-dashoffset into a [DashOffset] DashOffset parseDashOffset(XmlElement el) { - String rawDashOffset = getAttribute(el, 'stroke-dashoffset'); + final String rawDashOffset = getAttribute(el, 'stroke-dashoffset'); if (rawDashOffset == '') { return null; } @@ -184,7 +184,7 @@ double parseOpacity(XmlElement el) { /// Parses a @stroke attribute into a [Paint]. Paint parseStroke( XmlElement el, Rect bounds, Map paintServers) { - final rawStroke = getAttribute(el, 'stroke', def: 'none'); + final String rawStroke = getAttribute(el, 'stroke', def: 'none'); if (rawStroke == 'none') { return null; } @@ -192,7 +192,7 @@ Paint parseStroke( if (rawStroke.startsWith('url')) { return paintServers[rawStroke](bounds); } - var rawOpacity = getAttribute(el, 'stroke-opacity'); + final String rawOpacity = getAttribute(el, 'stroke-opacity'); final double opacity = rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); @@ -204,14 +204,14 @@ Paint parseStroke( paint.strokeCap = rawStrokeCap == 'null' ? StrokeCap.butt : StrokeCap.values.firstWhere( - (sc) => sc.toString() == 'StrokeCap.$rawStrokeCap', + (StrokeCap sc) => sc.toString() == 'StrokeCap.$rawStrokeCap', orElse: () => StrokeCap.butt); final String rawLineJoin = getAttribute(el, 'stroke-linejoin'); paint.strokeJoin = rawLineJoin == '' ? StrokeJoin.miter : StrokeJoin.values.firstWhere( - (sj) => sj.toString() == 'StrokeJoin.$rawLineJoin', + (StrokeJoin sj) => sj.toString() == 'StrokeJoin.$rawLineJoin', orElse: () => StrokeJoin.miter); final String rawMiterLimit = getAttribute(el, 'stroke-miterlimit'); diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index b24fcf372954..4ac5dafa6347 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -4,16 +4,16 @@ import 'package:xml/xml.dart'; import 'package:path_drawing/path_drawing.dart'; import 'package:vector_math/vector_math_64.dart'; -import 'vector_painter.dart'; import 'svg/colors.dart'; import 'svg/parsers.dart'; import 'svg/xml_parsers.dart'; import 'utilities/xml.dart'; +import 'vector_painter.dart'; typedef DrawableSvgShape SvgShapeFactory(XmlElement el, Map paintServers, DrawableStyle parentStyle); -final Map _shapes = { +final Map _shapes = { 'circle': (XmlElement el, Map paintServers, DrawableStyle parentStyle) => new DrawableSvgShape.fromSvgCircle(el, paintServers, parentStyle), @@ -41,42 +41,15 @@ final Map _shapes = { class DrawableSvgShape extends DrawableShape { const DrawableSvgShape(Path path, DrawableStyle style) : super(path, style); - /// Applies the transformation in the @transform attribute to the path. - static Path transformPath(Path path, XmlElement el) { - assert(path != null); - assert(el != null); - - final Matrix4 transform = - parseTransform(getAttribute(el, 'transform', def: null)); - - if (transform != null) { - return path.transform(transform.storage); - } else { - return path; - } - } - - static _createDrawable(Path path, Map paintServers, - XmlElement el, DrawableStyle parentStyle) { - assert(path != null); - - final Color defaultFill = parentStyle?.fill != null ? null : colorBlack; - - return new DrawableSvgShape( - transformPath(path, el), - parseStyle(el, paintServers, path.getBounds(), - defaultFillIfNotSpecified: defaultFill), - ); - } - /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgCircle(XmlElement el, Map paintServers, DrawableStyle parentStyle) { - final cx = double.parse(getAttribute(el, 'cx', def: '0')); - final cy = double.parse(getAttribute(el, 'cy', def: '0')); - final r = double.parse(getAttribute(el, 'r', def: '0')); - final oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); - final path = new Path()..addOval(oval); + final double cx = double.parse(getAttribute(el, 'cx', def: '0')); + final double cy = double.parse(getAttribute(el, 'cy', def: '0')); + final double r = double.parse(getAttribute(el, 'r', def: '0')); + final Rect oval = + new Rect.fromCircle(center: new Offset(cx, cy), radius: r); + final Path path = new Path()..addOval(oval); return _createDrawable(path, paintServers, el, parentStyle); } @@ -84,7 +57,7 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgPath(XmlElement el, Map paintServers, DrawableStyle parentStyle) { - final d = getAttribute(el, 'd'); + final String d = getAttribute(el, 'd'); final Path path = parseSvgPathData(d); return _createDrawable(path, paintServers, el, parentStyle); @@ -103,7 +76,7 @@ class DrawableSvgShape extends DrawableShape { rxRaw ??= ryRaw; ryRaw ??= rxRaw; - if ((rxRaw != null && rxRaw != '')) { + if (rxRaw != null && rxRaw != '') { final double rx = double.parse(rxRaw); final double ry = double.parse(ryRaw); @@ -115,18 +88,18 @@ class DrawableSvgShape extends DrawableShape { ); } - final path = new Path()..addRect(rect); + final Path path = new Path()..addRect(rect); return _createDrawable(path, paintServers, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG or element. factory DrawableSvgShape.fromSvgPolygonOrLine(XmlElement el, Map paintServers, DrawableStyle parentStyle) { - final points = getAttribute(el, 'points'); + final String points = getAttribute(el, 'points'); if (points == '') { return _createDrawable(null, paintServers, el, parentStyle); } - final path = parseSvgPathData('M' + points + 'z'); + final Path path = parseSvgPathData('M' + points + 'z'); return _createDrawable(path, paintServers, el, parentStyle); } @@ -134,12 +107,12 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgEllipse(XmlElement el, Map paintServers, DrawableStyle parentStyle) { - final cx = double.parse(getAttribute(el, 'cx', def: '0')); - final cy = double.parse(getAttribute(el, 'cy', def: '0')); - final rx = double.parse(getAttribute(el, 'rx', def: '0')); - final ry = double.parse(getAttribute(el, 'ry', def: '0')); + final double cx = double.parse(getAttribute(el, 'cx', def: '0')); + final double cy = double.parse(getAttribute(el, 'cy', def: '0')); + final double rx = double.parse(getAttribute(el, 'rx', def: '0')); + final double ry = double.parse(getAttribute(el, 'ry', def: '0')); - Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); + final Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); return _createDrawable( new Path()..addOval(r), paintServers, el, parentStyle); @@ -148,16 +121,47 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgLine(XmlElement el, Map paintServers, DrawableStyle parentStyle) { - final x1 = double.parse(getAttribute(el, 'x1', def: '0')); - final x2 = double.parse(getAttribute(el, 'x2', def: '0')); - final y1 = double.parse(getAttribute(el, 'y1', def: '0')); - final y2 = double.parse(getAttribute(el, 'y2', def: '0')); + final double x1 = double.parse(getAttribute(el, 'x1', def: '0')); + final double x2 = double.parse(getAttribute(el, 'x2', def: '0')); + final double y1 = double.parse(getAttribute(el, 'y1', def: '0')); + final double y2 = double.parse(getAttribute(el, 'y2', def: '0')); - final path = new Path() + final Path path = new Path() ..moveTo(x1, y1) ..lineTo(x2, y2); return _createDrawable(path, paintServers, el, parentStyle); } + + /// Applies the transformation in the @transform attribute to the path. + static Path transformPath(Path path, XmlElement el) { + assert(path != null); + assert(el != null); + + final Matrix4 transform = + parseTransform(getAttribute(el, 'transform', def: null)); + + if (transform != null) { + return path.transform(transform.storage); + } else { + return path; + } + } + + static DrawableSvgShape _createDrawable( + Path path, + Map paintServers, + XmlElement el, + DrawableStyle parentStyle) { + assert(path != null); + + final Color defaultFill = parentStyle?.fill != null ? null : colorBlack; + + return new DrawableSvgShape( + transformPath(path, el), + parseStyle(el, paintServers, path.getBounds(), + defaultFillIfNotSpecified: defaultFill), + ); + } } /// Creates a [Drawable] from an SVG or shape element. Also handles parsing and gradients. @@ -220,14 +224,14 @@ Drawable parseSvgGroup( final List children = []; final DrawableStyle style = parseStyle(el, paintServers, bounds, needsTransform: true); - el.children.forEach((child) { + for (XmlNode child in el.children) { if (child is XmlElement) { final Drawable el = parseSvgElement(child, paintServers, bounds, style); if (el != null) { children.add(el); } } - }); + } return new DrawableGroup( children, diff --git a/third_party/lib/src/utilities/xml.dart b/third_party/lib/src/utilities/xml.dart index 69f1326b424e..a9ac2cf398f3 100644 --- a/third_party/lib/src/utilities/xml.dart +++ b/third_party/lib/src/utilities/xml.dart @@ -14,7 +14,7 @@ String getAttribute(XmlElement el, String name, // but handling potential whitespace will get complicated and this just works. // I also don't feel like writing benchmarks for what is likely a micro-optimization. final List styles = style.split(';'); - raw = styles.firstWhere((str) => str.trimLeft().startsWith(name + ':'), + raw = styles.firstWhere((String str) => str.trimLeft().startsWith(name + ':'), orElse: () => ''); if (raw != '') { diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index e7e6183de7f8..72a691b918a7 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -21,7 +21,7 @@ abstract class Drawable { @immutable class DrawableStyle { final Paint stroke; - final CircularIntervalList dashArray; + final CircularIntervalList dashArray; final DashOffset dashOffset; final Paint fill; final Float64List transform; @@ -44,17 +44,19 @@ class DrawableStyle { /// /// If `other` is null, returns this. DrawableStyle mergeAndBlend(DrawableStyle other) { - if (other == null) return this; + if (other == null) { + return this; + } final DrawableStyle ret = new DrawableStyle( - fill: this.fill ?? other.fill, - stroke: this.stroke ?? other.stroke, - dashArray: this.dashArray ?? other.dashArray, - dashOffset: this.dashOffset ?? other.dashOffset, - transform: this.transform ?? other.transform, - textStyle: this.textStyle ?? other.textStyle, - pathFillType: this.pathFillType ?? other.pathFillType, - groupOpacity: mergeOpacity(this.groupOpacity, other.groupOpacity), + fill: fill ?? other.fill, + stroke: stroke ?? other.stroke, + dashArray: dashArray ?? other.dashArray, + dashOffset: dashOffset ?? other.dashOffset, + transform: transform ?? other.transform, + textStyle: textStyle ?? other.textStyle, + pathFillType: pathFillType ?? other.pathFillType, + groupOpacity: mergeOpacity(groupOpacity, other.groupOpacity), ); if (ret.fill != null) { @@ -90,7 +92,7 @@ class DrawableText implements Drawable { final DrawableStyle style; final Paragraph _paragraph; - DrawableText(text, this.offset, this.style) + DrawableText(String text, this.offset, this.style) : assert(text != null && text != ''), _paragraph = _buildParagraph(text, style); @@ -106,7 +108,7 @@ class DrawableText implements Drawable { bool get isVisible => _paragraph.width > 0.0; @override - draw(Canvas canvas, [DrawableStyle parentStyle]) { + void draw(Canvas canvas, [DrawableStyle parentStyle]) { canvas.drawParagraph(_paragraph, offset); } } @@ -160,8 +162,9 @@ class DrawableRoot implements Drawable { @override void draw(Canvas canvas, [DrawableStyle parentStyle]) { - children.forEach((child) => - child.draw(canvas, style?.mergeAndBlend(parentStyle) ?? parentStyle)); + for (Drawable child in children) { + child.draw(canvas, style?.mergeAndBlend(parentStyle) ?? parentStyle); + } } } @@ -185,7 +188,7 @@ class DrawableGroup implements Drawable { const DrawableGroup(this.children, this.style); @override - bool get isVisible => children != null && children.length > 0; + bool get isVisible => children != null && children.isNotEmpty; @override void draw(Canvas canvas, [DrawableStyle parentStyle]) { @@ -193,9 +196,9 @@ class DrawableGroup implements Drawable { canvas.save(); canvas.transform(style?.transform); } - children.forEach((child) { + for (Drawable child in children) { child.draw(canvas, style?.mergeAndBlend(parentStyle) ?? parentStyle); - }); + } if (style?.transform != null) { canvas.restore(); } @@ -207,10 +210,10 @@ class DrawableShape implements Drawable { final DrawableStyle style; final Path path; - Rect get bounds => path?.getBounds(); - const DrawableShape(this.path, this.style) : assert(path != null); + Rect get bounds => path?.getBounds(); + @override bool get isVisible => !bounds.isEmpty && (style?.stroke != null || style?.fill != null); @@ -252,7 +255,9 @@ class VectorPainter extends CustomPainter { p.hashCode; if (drawable == null || drawable.viewBox == null || - drawable.viewBox.size.width == 0) return; + drawable.viewBox.size.width == 0) { + return; + } drawable.scaleToViewBox(canvas, size); if (_clipToViewBox) { @@ -262,6 +267,8 @@ class VectorPainter extends CustomPainter { drawable.draw(canvas); } + // TODO: implement semanticsBuilder + @override - bool shouldRepaint(VectorPainter oldPainter) => true; + bool shouldRepaint(VectorPainter oldDelegate) => true; } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index dc13fe94e19c..f5dce9d1316b 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -1,20 +1,20 @@ import 'dart:async'; -import 'dart:io'; import 'dart:convert'; +import 'dart:io'; import 'package:flutter/services.dart' show rootBundle, AssetBundle; import 'package:flutter/widgets.dart'; import 'package:xml/xml.dart' hide parse; import 'package:xml/xml.dart' as xml show parse; -import 'vector_drawable.dart'; -import 'src/vector_painter.dart'; -import 'src/svg_parser.dart'; import 'src/svg/xml_parsers.dart'; +import 'src/svg_parser.dart'; +import 'src/vector_painter.dart'; +import 'vector_drawable.dart'; /// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. class SvgImage extends VectorDrawableImage { - SvgImage._(Future future, Size size, + const SvgImage._(Future future, Size size, {bool clipToViewBox, Key key, PaintLocation paintLocation}) : super(future, size, clipToViewBox: clipToViewBox, @@ -26,7 +26,7 @@ class SvgImage extends VectorDrawableImage { bool clipToViewBox = true, PaintLocation paintLocation = PaintLocation.Background}) { return new SvgImage._( - new Future.value(fromSvgString(svg, size)), + new Future.value(fromSvgString(svg, size)), size, clipToViewBox: clipToViewBox, key: key, @@ -68,7 +68,7 @@ class SvgImage extends VectorDrawableImage { DrawableRoot fromSvgString(String rawSvg, Size size) { final XmlElement svg = xml.parse(rawSvg).rootElement; final Rect viewBox = parseViewBox(svg); - Map paintServers = {}; + final Map paintServers = {}; final DrawableStyle style = parseStyle(svg, paintServers, viewBox); final List children = svg.children diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart index 139174626743..c3240d4f91ae 100644 --- a/third_party/lib/vector_drawable.dart +++ b/third_party/lib/vector_drawable.dart @@ -20,10 +20,11 @@ class VectorDrawableImage extends StatelessWidget { this.paintLocation = PaintLocation.Background}) : super(key: key); + @override Widget build(BuildContext context) { - return new FutureBuilder( + return new FutureBuilder( future: future, - builder: ((context, snapShot) { + builder: (BuildContext context, AsyncSnapshot snapShot) { if (snapShot.hasData) { final CustomPainter painter = new VectorPainter(snapShot.data, clipToViewBox: clipToViewBox); @@ -39,8 +40,8 @@ class VectorDrawableImage extends StatelessWidget { ), 0); } - return new LimitedBox(); - }), + return const LimitedBox(); + }, ); } } diff --git a/third_party/test/xml_test.dart b/third_party/test/xml_test.dart index aa1cc4867392..a3c35f604c30 100644 --- a/third_party/test/xml_test.dart +++ b/third_party/test/xml_test.dart @@ -21,7 +21,7 @@ void main() { }); // if the parsing logic changes, we can simplify some methods. for now assert that whitespace in attributes is preserved test('Attribute WhiteSpace test', () { - XmlDocument xd = + final XmlDocument xd = parse(''); expect( @@ -41,12 +41,12 @@ void main() { test('viewBox tests', () { final Rect rect = new Rect.fromLTWH(0.0, 0.0, 100.0, 100.0); - XmlElement svgWithViewBox = + final XmlElement svgWithViewBox = parse('').rootElement; - XmlElement svgWithViewBoxAndWidthHeight = + final XmlElement svgWithViewBoxAndWidthHeight = parse('') .rootElement; - XmlElement svgWithWidthHeight = + final XmlElement svgWithWidthHeight = parse('').rootElement; expect(parseViewBox(svgWithViewBox), rect); From 045095f56a48d240e57a16401bca8b30df0b9c15 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 11 May 2018 22:06:00 -0400 Subject: [PATCH 049/512] add flutter analyze to travis --- third_party/.travis.yml | 1 + third_party/pubspec.lock | 49 ++++++++++++---------------------------- 2 files changed, 15 insertions(+), 35 deletions(-) diff --git a/third_party/.travis.yml b/third_party/.travis.yml index bb9518ad4a53..f546e1c19d9b 100644 --- a/third_party/.travis.yml +++ b/third_party/.travis.yml @@ -13,6 +13,7 @@ before_script: - git clone https://github.com/flutter/flutter.git -b dev - ./flutter/bin/flutter doctor script: + - ./flutter/bin/flutter analyze - ./flutter/bin/flutter test cache: directories: diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 1be32dc60336..d27114340c6d 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -14,21 +14,14 @@ packages: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.4.2" + version: "1.4.3" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.0.6" - barback: - dependency: transitive - description: - name: barback - url: "https://pub.dartlang.org" - source: hosted - version: "0.15.2+15" + version: "2.0.7" boolean_selector: dependency: transitive description: @@ -43,13 +36,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.1" - cli_util: - dependency: transitive - description: - name: cli_util - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2+1" collection: dependency: transitive description: @@ -70,14 +56,14 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.0.2+1" + version: "2.0.3" csslib: dependency: transitive description: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.14.1" + version: "0.14.4" cupertino_icons: dependency: "direct main" description: @@ -136,7 +122,7 @@ packages: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.1" + version: "3.1.2" io: dependency: transitive description: @@ -144,13 +130,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.3.2+1" - isolate: - dependency: transitive - description: - name: isolate - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" js: dependency: transitive description: @@ -178,14 +157,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.1+4" + version: "0.12.2+1" meta: dependency: "direct main" description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.1.5" mime: dependency: transitive description: @@ -206,7 +185,7 @@ packages: name: node_preamble url: "https://pub.dartlang.org" source: hosted - version: "1.4.0" + version: "1.4.1" package_config: dependency: transitive description: @@ -262,7 +241,7 @@ packages: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.3.6" + version: "1.4.1" quiver: dependency: transitive description: @@ -276,7 +255,7 @@ packages: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "0.7.2" + version: "0.7.3" shelf_packages_handler: dependency: transitive description: @@ -316,7 +295,7 @@ packages: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.4" + version: "0.10.5" source_span: dependency: transitive description: @@ -337,7 +316,7 @@ packages: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "1.6.4" + version: "1.6.6" string_scanner: dependency: transitive description: @@ -358,7 +337,7 @@ packages: name: test url: "https://pub.dartlang.org" source: hosted - version: "0.12.34" + version: "0.12.37" typed_data: dependency: transitive description: @@ -409,5 +388,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.28.0 <=2.0.0-edge.c080951d45e79cd25df98036c4be835b284a269c" + dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.54.0.flutter-46ab040e58" flutter: ">=0.3.6 <2.0.0" From 167ca5a12c89f75dc2f8a846f7db635f93eeb625 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 13 May 2018 23:52:11 -0400 Subject: [PATCH 050/512] Fix arc, better none handling --- third_party/CHANGELOG.md | 6 +++++ third_party/example/main.dart | 1 + third_party/lib/src/svg/xml_parsers.dart | 17 +++++++----- third_party/lib/src/vector_painter.dart | 33 ++++++++++++++++++------ third_party/pubspec.lock | 13 +++------- third_party/pubspec.yaml | 8 ++---- 6 files changed, 47 insertions(+), 31 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 6e76a74cd8dc..a110d471fbaf 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGES +## 0.1.2 + +- Bump to path_drawing 0.2.3 (fix arc defect). +- Handle 'none' in dasharray without throwing exception. +- Better handling of inheritence and 'none' in fill/stroke/dasharray + ## 0.1.1 - Handle opacity on groups and inherited/blended opacity. diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 528f81567aa1..190bff2849ba 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -34,6 +34,7 @@ const List assetNames = const [ const List uriNames = const [ 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', + 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', ]; void main() => runApp(new MyApp()); diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 339fa02601bb..a509ed4e4a98 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -148,6 +148,8 @@ CircularIntervalList parseDashArray(XmlElement el) { final String rawDashArray = getAttribute(el, 'stroke-dasharray'); if (rawDashArray == '') { return null; + } else if (rawDashArray == 'none') { + return DrawableStyle.emptyDashArray; } final List parts = rawDashArray.split(new RegExp(r'[ ,]+')); @@ -184,9 +186,11 @@ double parseOpacity(XmlElement el) { /// Parses a @stroke attribute into a [Paint]. Paint parseStroke( XmlElement el, Rect bounds, Map paintServers) { - final String rawStroke = getAttribute(el, 'stroke', def: 'none'); - if (rawStroke == 'none') { + final String rawStroke = getAttribute(el, 'stroke'); + if (rawStroke == '') { return null; + } else if (rawStroke == 'none') { + return DrawableStyle.emptyPaint; } if (rawStroke.startsWith('url')) { @@ -226,15 +230,14 @@ Paint parseStroke( Paint parseFill(XmlElement el, Rect bounds, Map paintServers, Color defaultFillIfNotSpecified) { - final String rawFill = getAttribute(el, 'fill', def: null); - if (rawFill == null) { + final String rawFill = getAttribute(el, 'fill'); + if (rawFill == '') { if (defaultFillIfNotSpecified == null) { return null; } return new Paint()..color = defaultFillIfNotSpecified; - } - if (rawFill == 'none') { - return null; + } else if (rawFill == 'none') { + return DrawableStyle.emptyPaint; } if (rawFill.startsWith('url')) { diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 72a691b918a7..568edb58ef3c 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -20,6 +20,20 @@ abstract class Drawable { @immutable class DrawableStyle { + /// This should be used where 'stroke' or 'fill' are 'none'. + /// + /// This will not result in a drawing operation, but will clear out + /// inheritance. Modifying this paint should not result in any changes to + /// the image, but it should not be modified. + static final Paint emptyPaint = new Paint(); + + /// Used where 'dasharray' is 'none' + /// + /// This will not result in a drawing operation, but will clear out + /// inheritence. + static final CircularIntervalList emptyDashArray = + new CircularIntervalList(const []); + final Paint stroke; final CircularIntervalList dashArray; final DashOffset dashOffset; @@ -49,9 +63,11 @@ class DrawableStyle { } final DrawableStyle ret = new DrawableStyle( - fill: fill ?? other.fill, - stroke: stroke ?? other.stroke, - dashArray: dashArray ?? other.dashArray, + fill: identical(fill, emptyPaint) ? fill : fill ?? other.fill, + stroke: identical(stroke, emptyPaint) ? stroke : stroke ?? other.stroke, + dashArray: identical(dashArray, emptyDashArray) + ? dashArray + : dashArray ?? other.dashArray, dashOffset: dashOffset ?? other.dashOffset, transform: transform ?? other.transform, textStyle: textStyle ?? other.textStyle, @@ -60,8 +76,6 @@ class DrawableStyle { ); if (ret.fill != null) { - // print( - // 'before ${ret.fill.color} ${ret.groupOpacity} ${ret.fill.color.opacity} ${mergeOpacity(ret.fill.color.opacity, ret.groupOpacity)}'); ret.fill.color = ret.fill.color.withOpacity(ret.fill.color.opacity == 1.0 ? ret.groupOpacity ?? 1.0 : mergeOpacity(ret.groupOpacity, ret.fill.color.opacity)); @@ -223,12 +237,15 @@ class DrawableShape implements Drawable { final DrawableStyle localStyle = style.mergeAndBlend(parentStyle); path.fillType = localStyle.pathFillType ?? PathFillType.nonZero; - if (localStyle?.fill != null) { + if (localStyle?.fill != null && + !identical(localStyle.fill, DrawableStyle.emptyPaint)) { canvas.drawPath(path, localStyle.fill); } - if (localStyle?.stroke != null) { - if (localStyle.dashArray != null) { + if (localStyle?.stroke != null && + !identical(localStyle.stroke, DrawableStyle.emptyPaint)) { + if (localStyle.dashArray != null && + !identical(localStyle.dashArray, DrawableStyle.emptyDashArray)) { canvas.drawPath( dashPath(path, dashArray: localStyle.dashArray, diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index d27114340c6d..274ef01a5be2 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -63,14 +63,7 @@ packages: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.14.4" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - url: "https://pub.dartlang.org" - source: hosted - version: "0.1.2" + version: "0.14.3" flutter: dependency: "direct main" description: flutter @@ -213,7 +206,7 @@ packages: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.2.2" + version: "0.2.3" petitparser: dependency: transitive description: @@ -388,5 +381,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.54.0.flutter-46ab040e58" + dart: ">=2.0.0-dev.52.0 <=2.0.0-edge.c080951d45e79cd25df98036c4be835b284a269c" flutter: ">=0.3.6 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 71aa1b5d36f0..268b18460608 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,20 +2,16 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.1.1 +version: 0.1.2 dependencies: - path_drawing: ^0.2.2 + path_drawing: ^0.2.3 xml: ^3.0.0 vector_math: ^2.0.4 meta: ^1.1.2 flutter: sdk: flutter - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^0.1.0 - dev_dependencies: test: ^0.12.34 flutter_test: From db430ab7aeb9b08ee9c18c27949a933ddd0ac5f9 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 14 May 2018 21:36:08 -0400 Subject: [PATCH 051/512] render tests! --- third_party/assets/wikimedia/chess_knight.svg | 23 ++++++ third_party/example/main.dart | 1 + third_party/golden/dart.png | Bin 0 -> 4549 bytes .../deborah_ufw/new-action-expander.png | Bin 0 -> 8428 bytes third_party/golden/deborah_ufw/new-camera.png | Bin 0 -> 8273 bytes .../golden/deborah_ufw/new-gif-button.png | Bin 0 -> 8612 bytes third_party/golden/deborah_ufw/new-gif.png | Bin 0 -> 4813 bytes third_party/golden/deborah_ufw/new-image.png | Bin 0 -> 8258 bytes .../golden/deborah_ufw/new-mention.png | Bin 0 -> 7299 bytes .../golden/deborah_ufw/new-pause-button.png | Bin 0 -> 7531 bytes .../golden/deborah_ufw/new-play-button.png | Bin 0 -> 7742 bytes .../golden/deborah_ufw/new-send-circle.png | Bin 0 -> 10504 bytes third_party/golden/deborah_ufw/numeric_25.png | Bin 0 -> 2809 bytes third_party/golden/flutter_logo.png | Bin 0 -> 2763 bytes third_party/golden/simple/dash_path.png | Bin 0 -> 844 bytes third_party/golden/simple/ellipse.png | Bin 0 -> 2767 bytes third_party/golden/simple/group_opacity.png | Bin 0 -> 4140 bytes third_party/golden/simple/linear_gradient.png | Bin 0 -> 1845 bytes .../golden/simple/linear_gradient_2.png | Bin 0 -> 745 bytes third_party/golden/simple/nested_group.png | Bin 0 -> 2841 bytes third_party/golden/simple/radial_gradient.png | Bin 0 -> 3285 bytes third_party/golden/simple/rect_rrect.png | Bin 0 -> 2945 bytes third_party/golden/simple/style_attr.png | Bin 0 -> 1097 bytes third_party/golden/w3samples/aa.png | Bin 0 -> 6742 bytes third_party/golden/w3samples/alphachannel.png | Bin 0 -> 6864 bytes .../golden/wikimedia/Ghostscript_Tiger.png | Bin 0 -> 44393 bytes third_party/golden/wikimedia/chess_knight.png | Bin 0 -> 6733 bytes third_party/lib/src/vector_painter.dart | 8 +- third_party/lib/vector_drawable.dart | 2 +- third_party/pubspec.lock | 8 +- third_party/pubspec.yaml | 3 + third_party/test/render_svg_test.dart | 40 ++++++++++ third_party/tool/gen_golden.dart | 74 ++++++++++++++++++ 33 files changed, 150 insertions(+), 9 deletions(-) create mode 100644 third_party/assets/wikimedia/chess_knight.svg create mode 100644 third_party/golden/dart.png create mode 100644 third_party/golden/deborah_ufw/new-action-expander.png create mode 100644 third_party/golden/deborah_ufw/new-camera.png create mode 100644 third_party/golden/deborah_ufw/new-gif-button.png create mode 100644 third_party/golden/deborah_ufw/new-gif.png create mode 100644 third_party/golden/deborah_ufw/new-image.png create mode 100644 third_party/golden/deborah_ufw/new-mention.png create mode 100644 third_party/golden/deborah_ufw/new-pause-button.png create mode 100644 third_party/golden/deborah_ufw/new-play-button.png create mode 100644 third_party/golden/deborah_ufw/new-send-circle.png create mode 100644 third_party/golden/deborah_ufw/numeric_25.png create mode 100644 third_party/golden/flutter_logo.png create mode 100644 third_party/golden/simple/dash_path.png create mode 100644 third_party/golden/simple/ellipse.png create mode 100644 third_party/golden/simple/group_opacity.png create mode 100644 third_party/golden/simple/linear_gradient.png create mode 100644 third_party/golden/simple/linear_gradient_2.png create mode 100644 third_party/golden/simple/nested_group.png create mode 100644 third_party/golden/simple/radial_gradient.png create mode 100644 third_party/golden/simple/rect_rrect.png create mode 100644 third_party/golden/simple/style_attr.png create mode 100644 third_party/golden/w3samples/aa.png create mode 100644 third_party/golden/w3samples/alphachannel.png create mode 100644 third_party/golden/wikimedia/Ghostscript_Tiger.png create mode 100644 third_party/golden/wikimedia/chess_knight.png create mode 100644 third_party/test/render_svg_test.dart create mode 100644 third_party/tool/gen_golden.dart diff --git a/third_party/assets/wikimedia/chess_knight.svg b/third_party/assets/wikimedia/chess_knight.svg new file mode 100644 index 000000000000..eabd2af51a23 --- /dev/null +++ b/third_party/assets/wikimedia/chess_knight.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 190bff2849ba..174a18539b62 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -28,6 +28,7 @@ const List assetNames = const [ 'assets/simple/ellipse.svg', 'assets/simple/dash_path.svg', 'assets/simple/nested_group.svg', + 'assets/wikimedia/chess_knight.svg', 'assets/wikimedia/Ghostscript_Tiger.svg', ]; diff --git a/third_party/golden/dart.png b/third_party/golden/dart.png new file mode 100644 index 0000000000000000000000000000000000000000..3526c7563521801bc6f98c80741f339d402e8e85 GIT binary patch literal 4549 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 AiU0rr literal 0 HcmV?d00001 diff --git a/third_party/golden/deborah_ufw/new-action-expander.png b/third_party/golden/deborah_ufw/new-action-expander.png new file mode 100644 index 0000000000000000000000000000000000000000..de6f20950783acaeda2152fd9068b8692c4650e8 GIT binary patch literal 8428 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 LZz+{2Scd&Cn`;TY literal 0 HcmV?d00001 diff --git a/third_party/golden/deborah_ufw/new-gif-button.png b/third_party/golden/deborah_ufw/new-gif-button.png new file mode 100644 index 0000000000000000000000000000000000000000..d941059fe957a193f5a8cda1ab753b506918d00f GIT binary patch literal 8612 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 Vvl&~9@T3JoOI=s3LgilA{{yECY)AkA literal 0 HcmV?d00001 diff --git a/third_party/golden/deborah_ufw/new-gif.png b/third_party/golden/deborah_ufw/new-gif.png new file mode 100644 index 0000000000000000000000000000000000000000..6cbc72d5ad60eb750bbbda0e4b5c8d118d3992f2 GIT binary patch literal 4813 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 SXu&Nhh=!W3Dqi_<@V@}S9WU|# literal 0 HcmV?d00001 diff --git a/third_party/golden/deborah_ufw/new-image.png b/third_party/golden/deborah_ufw/new-image.png new file mode 100644 index 0000000000000000000000000000000000000000..ee0373158010216661cdad990999d66ab1dca85e GIT binary patch literal 8258 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 literal 0 HcmV?d00001 diff --git a/third_party/golden/deborah_ufw/new-pause-button.png b/third_party/golden/deborah_ufw/new-pause-button.png new file mode 100644 index 0000000000000000000000000000000000000000..37b1f5ee6d33463582f85c5d2aa72ca79355f567 GIT binary patch literal 7531 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 literal 0 HcmV?d00001 diff --git a/third_party/golden/deborah_ufw/new-play-button.png b/third_party/golden/deborah_ufw/new-play-button.png new file mode 100644 index 0000000000000000000000000000000000000000..d4e5a90b1be6befaa681e0acf91ecc45a1c0f282 GIT binary patch literal 7742 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 S{rPqVjG-*AE>|gI5%xdLb+vc^ literal 0 HcmV?d00001 diff --git a/third_party/golden/deborah_ufw/new-send-circle.png b/third_party/golden/deborah_ufw/new-send-circle.png new file mode 100644 index 0000000000000000000000000000000000000000..d9c4f23c900752697a5f2c0a1c05232d2f78f724 GIT binary patch literal 10504 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 A$p8QV literal 0 HcmV?d00001 diff --git a/third_party/golden/flutter_logo.png b/third_party/golden/flutter_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..09b2a54adbbc766655a38c3dd592152848bccee8 GIT binary patch literal 2763 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 literal 0 HcmV?d00001 diff --git a/third_party/golden/simple/linear_gradient_2.png b/third_party/golden/simple/linear_gradient_2.png new file mode 100644 index 0000000000000000000000000000000000000000..4547d893b73f6665d158efb652154102ac263f39 GIT binary patch literal 745 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q|do-U3d6?5L+G4zuT6luHodxChwo#peDChcurvSf+Z*`Q5RmiW5Pf7^b|&(hBoXMg;(tlm1ecm9U!!q1NWJa6&)V6|-3 zw~M=M-@TK2_2|*%+x$yby?PXTb$Y*W?!Bn1k+t6#MvB~Ef&C|Djl4ViCZ8zSy+I%+c_j})l*x6?{`V)~lKuYrO`v2@P UnVEdF(G$e=boFyt=akR{0LG^MKL7v# literal 0 HcmV?d00001 diff --git a/third_party/golden/simple/nested_group.png b/third_party/golden/simple/nested_group.png new file mode 100644 index 0000000000000000000000000000000000000000..993bafc849987b8c105ad95f60d38a6578750009 GIT binary patch literal 2841 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 Hd*VLVJUX<4B-HR z8jh3>1_tKOo-U3d6?5L++S@1MF4Fe!nA7ZtK7|cWxNrXESO35&5S@J?OMvsI#X-)d z{<|;N%@6)-QyDt<$yLu+XWy3X&ON~Y*Q|>-Nn1IeFepV%ci>Z+WXk!(K`FA|flqDHR*of% z6W2H^^me51GG%(GeC1qXIPr?w1U{Fb=?+$cp1w>kfr1=Mj3-`En!xB1)b7A0=*i0@ z>7nvj_=Ml|)2Y`hC!X_R82Sc(iLu5nf1?MRVj z%5+i57VvOZTIsLQ+quN7u|#3gE|yE39$7*j?n*1&73Ov>5o_d8m}JFb)ZvjOaKb@p z=6nY>;gfe*j2I`L@m82DaB>cdk>JEL?h2CyPsXqqDNa1&tT0*VqzsFZ;lv*G2`4*K zbQ(nzCKa*-wRjv8@K98G>8~*N@5c`tUhnbvCFGI5-`=KUi2(KOINGs9zfnYGQXNas z6pvp59*Ihs{t8Dsm*_U?IH}vm7Rkfu3nFs#c( z!DOSC3e&=wqDq1szM=gJj;|15N9xP7gqRN6Cv7y~A3MJv1LX8G4Q$6n8$=e=% zS-k7#@5AjEl|OjZ@2$W8=KVBYr%GM(PKOAm)gCN|jG|nW1g3o|*_(GhexFR)e20j0 z_UF&Hy8;DELR6R%Bi%vr+suU;H|(*U$k7tK1IR3p`tI^bUyQ|!IyvkQ`w(1qgQu&X%Q~loCIIgybld;{ literal 0 HcmV?d00001 diff --git a/third_party/golden/w3samples/aa.png b/third_party/golden/w3samples/aa.png new file mode 100644 index 0000000000000000000000000000000000000000..9cc2f293b2c5a695ee3b63ae32a8640720d8be0d GIT binary patch literal 6742 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 S>4Ci=JQYPv1+?7jp#K4J87eUV literal 0 HcmV?d00001 diff --git a/third_party/golden/w3samples/alphachannel.png b/third_party/golden/w3samples/alphachannel.png new file mode 100644 index 0000000000000000000000000000000000000000..bf7d6caa27592c6614ae543e87fa59a498599b12 GIT binary patch literal 6864 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 literal 0 HcmV?d00001 diff --git a/third_party/golden/wikimedia/Ghostscript_Tiger.png b/third_party/golden/wikimedia/Ghostscript_Tiger.png new file mode 100644 index 0000000000000000000000000000000000000000..977f1ea17de3a4f7d53c40390e2c5592be3d4345 GIT binary patch literal 44393 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 T1zOz5Eg^uiyt-Vq3^eS2C*;Xc literal 0 HcmV?d00001 diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 568edb58ef3c..efc180cc52e9 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -148,7 +148,7 @@ class DrawableRoot implements Drawable { /// If the `viewBox` dimensions are not 1:1 with `desiredSize`, will scale to /// the smaller dimension and translate to center the image along the larger /// dimension. - void scaleToViewBox(Canvas canvas, Size desiredSize) { + void scaleCanvasToViewBox(Canvas canvas, Size desiredSize) { final double xscale = desiredSize.width / viewBox.size.width; final double yscale = desiredSize.height / viewBox.size.height; @@ -166,7 +166,7 @@ class DrawableRoot implements Drawable { } /// Clips the canvas to a rect corresponding to the `viewBox`. - void clipToViewBox(Canvas canvas) { + void clipCanvasToViewBox(Canvas canvas) { canvas.clipRect(viewBox.translate(viewBox.left, viewBox.top)); } @@ -276,9 +276,9 @@ class VectorPainter extends CustomPainter { return; } - drawable.scaleToViewBox(canvas, size); + drawable.scaleCanvasToViewBox(canvas, size); if (_clipToViewBox) { - drawable.clipToViewBox(canvas); + drawable.clipCanvasToViewBox(canvas); } drawable.draw(canvas); diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart index c3240d4f91ae..3f06bf8ce83e 100644 --- a/third_party/lib/vector_drawable.dart +++ b/third_party/lib/vector_drawable.dart @@ -7,7 +7,7 @@ import 'src/vector_painter.dart'; enum PaintLocation { Foreground, Background } -/// Handles rendering [Drawables] to a canvas. +/// Handles rendering [Drawable]s to a canvas. class VectorDrawableImage extends StatelessWidget { final Size size; final Future future; diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 274ef01a5be2..7a0f6c08310e 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -63,7 +63,7 @@ packages: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.14.3" + version: "0.14.4" flutter: dependency: "direct main" description: flutter @@ -82,7 +82,7 @@ packages: source: hosted version: "0.1.0-alpha.12" glob: - dependency: transitive + dependency: "direct dev" description: name: glob url: "https://pub.dartlang.org" @@ -194,7 +194,7 @@ packages: source: hosted version: "1.0.2" path: - dependency: transitive + dependency: "direct dev" description: name: path url: "https://pub.dartlang.org" @@ -381,5 +381,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.52.0 <=2.0.0-edge.c080951d45e79cd25df98036c4be835b284a269c" + dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.54.0.flutter-46ab040e58" flutter: ">=0.3.6 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 268b18460608..ebc0fb45c963 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -13,6 +13,8 @@ dependencies: sdk: flutter dev_dependencies: + glob: ^1.1.5 + path: ^1.5.1 test: ^0.12.34 flutter_test: sdk: flutter @@ -56,6 +58,7 @@ flutter: - assets/simple/text.svg - assets/simple/style_attr.svg - assets/wikimedia/Ghostscript_Tiger.svg + - assets/wikimedia/chess_knight.svg - assets/android_vd/battery_charging.xml environment: diff --git a/third_party/test/render_svg_test.dart b/third_party/test/render_svg_test.dart new file mode 100644 index 000000000000..58ee14673f96 --- /dev/null +++ b/third_party/test/render_svg_test.dart @@ -0,0 +1,40 @@ +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:path/path.dart'; + +import 'package:test/test.dart'; + +import '../tool/gen_golden.dart' as golden; + +Iterable getGoldenFileNames() sync* { + final Directory dir = new Directory(join(dirname(Platform.script.path), + dirname(Platform.script.path).endsWith('test') ? '..' : '', 'golden')); + for (FileSystemEntity fe in dir.listSync(recursive: true)) { + if (fe is File && fe.path.toLowerCase().endsWith('.png')) { + yield fe; + } + } +} + +String getSvgAssetName(String goldenFileName) { + return goldenFileName + .replaceAll('/golden/', '/assets/') + .replaceAll('\\golden\\', '\\assets\\') + .replaceAll('.png', '.svg'); +} + +void main() { + test('SVG Rendering matches golden files', () async { + for (File goldenFile in getGoldenFileNames()) { + final File svgAssetFile = + new File(getSvgAssetName(goldenFile.path)); + final Uint8List bytes = + await golden.getSvgPngBytes(await svgAssetFile.readAsString()); + + final Uint8List goldenBytes = await goldenFile.readAsBytes(); + + expect(bytes, orderedEquals(goldenBytes), reason: '${goldenFile.path} does not match rendered output of ${svgAssetFile.path}!'); + } + }); +} diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart new file mode 100644 index 000000000000..ee0c74e4d044 --- /dev/null +++ b/third_party/tool/gen_golden.dart @@ -0,0 +1,74 @@ +// There's probably some better way to do this, but for now run `flutter test tool/gen_golden.dart +// should exclude files that +// - aren't rendering properly +// - have text (this doesn't render properly in the host setup?) +// The golden files should then be visually compared against Chrome's rendering output for correctness. +// The comparison may have to be made more tolerant if we want to use other sources of rendering for comparison... + +import 'dart:async'; +import 'dart:io'; +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:path/path.dart' as path; + +import 'package:flutter_svg/svg.dart' as svg; +import 'package:flutter_svg/src/vector_painter.dart'; + +Future getSvgPngBytes(String svgData) async { + final PictureRecorder rec = new PictureRecorder(); + final Canvas canvas = new Canvas(rec); + + const Size size = const Size(200.0, 200.0); + + final DrawableRoot svgRoot = svg.fromSvgString(svgData, size); + svgRoot.scaleCanvasToViewBox(canvas, size); + svgRoot.clipCanvasToViewBox(canvas); + + canvas.drawPaint(new Paint()..color = const Color(0xFFFFFFFF)); + svgRoot.draw(canvas); + + final Picture pict = rec.endRecording(); + + final Image image = pict.toImage(size.width.toInt(), size.height.toInt()); + final ByteData bytes = await image.toByteData(format: ImageByteFormat.png); + + return bytes.buffer.asUint8List(); +} + +final Set badSvgFiles = new Set.of([ + 'simple/text.svg', +]); + +Iterable getSvgFileNames() sync* { + final Directory dir = new Directory('./assets'); + for (FileSystemEntity fe in dir.listSync(recursive: true)) { + if (fe is File && + fe.path.toLowerCase().endsWith('.svg') && + !badSvgFiles.contains(fe.path + .substring(fe.path.lastIndexOf(new RegExp(r'[\\/]assets')) + 8))) { + yield fe; + } + } +} + + +String getGoldenFileName(String svgAssetPath) { + return svgAssetPath + .replaceAll('/assets/', '/golden/') + .replaceAll('\\assets\\', '\\golden\\') + .replaceAll('.svg', '.png'); +} + +Future main() async { + for (File fe in getSvgFileNames()) { + final String pathName = getGoldenFileName(fe.path); + + final Directory goldenDir = new Directory(path.dirname(pathName)); + if (!goldenDir.existsSync()) { + goldenDir.createSync(recursive: true); + } + final File output = new File(pathName); + await output.writeAsBytes(await getSvgPngBytes(await fe.readAsString())); + } +} From c4f0c2148007c03345012ca9a3eca4820bd12f93 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 14 May 2018 22:08:48 -0400 Subject: [PATCH 052/512] support different spreadModes --- third_party/lib/src/svg/xml_parsers.dart | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index a509ed4e4a98..b5bfac765483 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -58,6 +58,20 @@ double _parseDecimalOrPercentage(String val) { } } +TileMode parseTileMode(XmlElement el) { + final String spreadMethod = getAttribute(el, 'spreadMethod', def: 'pad'); + switch (spreadMethod) { + case 'pad': + return TileMode.clamp; + case 'repeat': + return TileMode.repeated; + case 'reflect': + return TileMode.mirror; + default: + return TileMode.clamp; + } +} + /// Parses an SVG element into a [Paint]. Paint parseLinearGradient(XmlElement el, Rect bounds) { final double x1 = @@ -69,6 +83,8 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { final double y2 = _parseDecimalOrPercentage(getAttribute(el, 'y2', def: '0%')); + final TileMode spreadMethod = parseTileMode(el); + final Offset from = new Offset( bounds.left + (bounds.width * x1), bounds.left + (bounds.height * y1), @@ -91,6 +107,7 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { final String rawOffset = getAttribute(stop, 'offset'); return _parseDecimalOrPercentage(rawOffset); }).toList(), + spreadMethod, ); return new Paint()..shader = gradient; @@ -108,6 +125,7 @@ Paint parseRadialGradient(XmlElement el, Rect bounds) { final double fy = _parseDecimalOrPercentage(getAttribute(el, 'fy', def: rawCy)); + final TileMode spreadMethod = parseTileMode(el); if (fx != cx || fy != cy) { throw new UnsupportedError( 'Focal points not supported by this implementation'); @@ -126,6 +144,7 @@ Paint parseRadialGradient(XmlElement el, Rect bounds) { final String rawOffset = getAttribute(stop, 'offset'); return _parseDecimalOrPercentage(rawOffset); }).toList(), + spreadMethod, ); return new Paint()..shader = gradient; From eb7a998d8b6713489be908a910de15f2fe543055 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 14 May 2018 22:15:16 -0400 Subject: [PATCH 053/512] add coverage --- third_party/.travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/third_party/.travis.yml b/third_party/.travis.yml index f546e1c19d9b..efa9d9dfe0e4 100644 --- a/third_party/.travis.yml +++ b/third_party/.travis.yml @@ -12,9 +12,12 @@ addons: before_script: - git clone https://github.com/flutter/flutter.git -b dev - ./flutter/bin/flutter doctor + - gem install coveralls-lcov script: - ./flutter/bin/flutter analyze - ./flutter/bin/flutter test +after_success: + - coveralls-lcov coverage/lcov.info cache: directories: - $HOME/.pub-cache \ No newline at end of file From c216bc835ee04ca01a024b8d5ea9e5b48cede755 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 14 May 2018 22:23:15 -0400 Subject: [PATCH 054/512] coverage --- third_party/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/.travis.yml b/third_party/.travis.yml index efa9d9dfe0e4..84fb7c548047 100644 --- a/third_party/.travis.yml +++ b/third_party/.travis.yml @@ -15,7 +15,7 @@ before_script: - gem install coveralls-lcov script: - ./flutter/bin/flutter analyze - - ./flutter/bin/flutter test + - ./flutter/bin/flutter test --coverage after_success: - coveralls-lcov coverage/lcov.info cache: From 0c9c34d1dcae8c1e958e876c178711b0275c45ce Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 15 May 2018 00:02:16 -0400 Subject: [PATCH 055/512] add more unit tests, minor bug fixes from unit testing --- third_party/lib/src/svg/colors.dart | 3 +- third_party/lib/src/svg/parsers.dart | 26 ++++---- third_party/lib/src/svg/xml_parsers.dart | 2 +- third_party/lib/src/vector_painter.dart | 21 +++++- third_party/test/colors_svg_test.dart | 20 ++++++ third_party/test/parser_svg_test.dart | 66 +++++++++++++++++++ .../test/{xml_test.dart => xml_svg_test.dart} | 0 7 files changed, 120 insertions(+), 18 deletions(-) create mode 100644 third_party/test/colors_svg_test.dart create mode 100644 third_party/test/parser_svg_test.dart rename third_party/test/{xml_test.dart => xml_svg_test.dart} (100%) diff --git a/third_party/lib/src/svg/colors.dart b/third_party/lib/src/svg/colors.dart index 2ea10f1895db..d090c1b62e11 100644 --- a/third_party/lib/src/svg/colors.dart +++ b/third_party/lib/src/svg/colors.dart @@ -58,8 +58,7 @@ Color parseColor(String colorString) { return namedColor; } - throw new ArgumentError.value( - colorString, 'colorString', 'Incorrectly formatted color $colorString'); + throw new StateError('Could not parse "$colorString" as a color.'); } // https://www.w3.org/TR/SVG11/types.html#ColorKeywords diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index d0864c122be9..14ff18ff80cb 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -19,7 +19,7 @@ const Map _matrixParsers = const { }; /// Parses a SVG transform attribute into a [Matrix4]. -/// +/// /// Based on work in the "vi-tool" by @amirh, but extended to support additional /// transforms and use a Matrix4 rather than Matrix3 for the affine matrices. Matrix4 parseTransform(String transform) { @@ -28,7 +28,7 @@ Matrix4 parseTransform(String transform) { } if (!_transformValidator.hasMatch(transform)) - throw new Exception('illegal or unsupported transform: $transform'); + throw new StateError('illegal or unsupported transform: $transform'); final Iterable matches = _transformCommand.allMatches(transform).toList().reversed; Matrix4 result = new Matrix4.identity(); @@ -38,7 +38,7 @@ Matrix4 parseTransform(String transform) { final MatrixParser transformer = _matrixParsers[command]; if (transformer == null) { - throw new FormatException('Unsupported transform: $command'); + throw new StateError('Unsupported transform: $command'); } result = transformer(params, result); @@ -64,12 +64,12 @@ Matrix4 _parseSvgMatrix(String paramsStr, Matrix4 current) { Matrix4 _parseSvgSkewX(String paramsStr, Matrix4 current) { final double x = double.parse(paramsStr); - return _affineMatrix(1.0, tan(x), 0.0, 0.0, 1.0, 0.0).multiplied(current); + return _affineMatrix(1.0, 0.0, tan(x), 1.0, 0.0, 0.0).multiplied(current); } Matrix4 _parseSvgSkewY(String paramsStr, Matrix4 current) { final double y = double.parse(paramsStr); - return _affineMatrix(1.0, 0.0, 0.0, tan(y), 1.0, 0.0).multiplied(current); + return _affineMatrix(1.0, tan(y), 0.0, 1.0, 0.0, 0.0).multiplied(current); } Matrix4 _parseSvgTranslate(String paramsStr, Matrix4 current) { @@ -95,7 +95,8 @@ Matrix4 _parseSvgRotate(String paramsStr, Matrix4 current) { assert(params.length <= 3); final double a = radians(double.parse(params[0])); - final Matrix4 rotate = _affineMatrix(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0); + final Matrix4 rotate = + _affineMatrix(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0); if (params.length > 1) { final double x = double.parse(params[1]); @@ -109,15 +110,16 @@ Matrix4 _parseSvgRotate(String paramsStr, Matrix4 current) { } } -Matrix4 _affineMatrix(double a, double b, double c, double d, double e, double f) { +Matrix4 _affineMatrix( + double a, double b, double c, double d, double e, double f) { return new Matrix4( a, b, 0.0, 0.0, c, d, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, e, f, 0.0, 1.0); } - PathFillType parseRawFillRule(String rawFillRule) { - if (rawFillRule == '' || rawFillRule == null) { - return PathFillType.nonZero; + if (rawFillRule == 'inherit' || rawFillRule == null) { + return null; } - return rawFillRule != 'nonzero' ? PathFillType.evenOdd : PathFillType.nonZero; -} \ No newline at end of file + + return rawFillRule != 'evenodd' ? PathFillType.nonZero : PathFillType.evenOdd; +} diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index b5bfac765483..f5f1d3332426 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -276,6 +276,6 @@ Paint parseFill(XmlElement el, Rect bounds, } PathFillType parseFillRule(XmlElement el) { - final String rawFillRule = getAttribute(el, 'fill-rule', def: 'nonzero'); + final String rawFillRule = getAttribute(el, 'fill-rule', def: null); return parseRawFillRule(rawFillRule); } diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index efc180cc52e9..b5fed4d5281a 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -15,7 +15,7 @@ abstract class Drawable { /// Draws the contents or children of this [Drawable] to the `canvas`, using /// the `parentPaint` to optionally override the child's paint. - void draw(Canvas canvas, [DrawableStyle parentStyle]); + void draw(Canvas canvas, [DrawableStyle parentStyle]) {} } @immutable @@ -123,6 +123,9 @@ class DrawableText implements Drawable { @override void draw(Canvas canvas, [DrawableStyle parentStyle]) { + if (!isVisible) { + return; + } canvas.drawParagraph(_paragraph, offset); } } @@ -176,6 +179,9 @@ class DrawableRoot implements Drawable { @override void draw(Canvas canvas, [DrawableStyle parentStyle]) { + if (!isVisible) { + return; + } for (Drawable child in children) { child.draw(canvas, style?.mergeAndBlend(parentStyle) ?? parentStyle); } @@ -206,6 +212,9 @@ class DrawableGroup implements Drawable { @override void draw(Canvas canvas, [DrawableStyle parentStyle]) { + if (!isVisible) { + return; + } if (style?.transform != null) { canvas.save(); canvas.transform(style?.transform); @@ -228,12 +237,18 @@ class DrawableShape implements Drawable { Rect get bounds => path?.getBounds(); + // can't use bounds.isEmpty here because some paths give a 0 width or height + // see https://skia.org/user/api/SkPath_Reference#SkPath_getBounds + // can't rely on style because parent style may end up filling or stroking + // TODO: implement display properties @override - bool get isVisible => - !bounds.isEmpty && (style?.stroke != null || style?.fill != null); + bool get isVisible => bounds.width + bounds.height > 0; @override void draw(Canvas canvas, [DrawableStyle parentStyle]) { + if (!isVisible) { + return; + } final DrawableStyle localStyle = style.mergeAndBlend(parentStyle); path.fillType = localStyle.pathFillType ?? PathFillType.nonZero; diff --git a/third_party/test/colors_svg_test.dart b/third_party/test/colors_svg_test.dart new file mode 100644 index 000000000000..5f17b7cd5619 --- /dev/null +++ b/third_party/test/colors_svg_test.dart @@ -0,0 +1,20 @@ +import 'dart:ui' show Color; + +import 'package:test/test.dart'; +import 'package:flutter_svg/src/svg/colors.dart'; + +void main() { + const Color white = const Color(0xFFFFFFFF); + const Color black = const Color(0xFF000000); + test('Color Tests', () { + expect(parseColor('#FFFFFF'), white); + expect(parseColor('white'), white); + expect(parseColor('rgb(255, 255, 255)'), white); + expect(parseColor('rgb(100%, 100%, 100%)'), white); + expect(parseColor('rgba(255,255, 255, 255)'), white); + expect(parseColor('#DDFFFFFF'), const Color(0xDDFFFFFF)); + expect(parseColor(''), black); + expect(parseColor('none'), null); + expect(() => parseColor('invalid name'), throwsStateError); + }); +} diff --git a/third_party/test/parser_svg_test.dart b/third_party/test/parser_svg_test.dart new file mode 100644 index 000000000000..6b6da920979f --- /dev/null +++ b/third_party/test/parser_svg_test.dart @@ -0,0 +1,66 @@ +import 'dart:ui' show PathFillType; + +import 'package:flutter_svg/src/svg/parsers.dart'; +import 'package:test/test.dart'; +import 'package:vector_math/vector_math_64.dart'; + +void main() { + test('SVG value parser tests', () { + expect(() => parseTransform('invalid'), throwsStateError); + expect(() => parseTransform('transformunsupported(0,0)'), throwsStateError); + + expect(parseTransform('skewX(60)'), new Matrix4.skewX(60.0)); + expect(parseTransform('skewY(60)'), new Matrix4.skewY(60.0)); + expect(parseTransform('translate(10)'), + new Matrix4.translationValues(10.0, 10.0, 0.0)); + expect(parseTransform('translate(10, 15)'), + new Matrix4.translationValues(10.0, 15.0, 0.0)); + + expect(parseTransform('scale(10)'), + new Matrix4.identity()..scale(10.0, 10.0, 1.0)); + expect(parseTransform('scale(10, 15)'), + new Matrix4.identity()..scale(10.0, 15.0, 1.0)); + + expect(parseTransform('rotate(20)'), new Matrix4.rotationZ(radians(20.0))); + expect( + parseTransform('rotate(20, 30)'), + new Matrix4.identity() + ..translate(30.0, 30.0) + ..rotateZ(radians(20.0)) + ..translate(-30.0, -30.0)); + expect( + parseTransform('rotate(20, 30, 40)'), + new Matrix4.identity() + ..translate(30.0, 40.0) + ..rotateZ(radians(20.0)) + ..translate(-30.0, -40.0)); + + expect( + parseTransform('matrix(1.5, 2.0, 3.0, 4.0, 5.0, 6.0)'), + new Matrix4.fromList([ + 1.5, + 2.0, + 0.0, + 0.0, + 3.0, + 4.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 5.0, + 6.0, + 0.0, + 1.0 + ])); + + expect(parseRawFillRule(''), PathFillType.nonZero); + expect(parseRawFillRule(null), isNull); + expect(parseRawFillRule('inherit'), isNull); + expect(parseRawFillRule('nonzero'), PathFillType.nonZero); + expect(parseRawFillRule('evenodd'), PathFillType.evenOdd); + expect(parseRawFillRule('invalid'), PathFillType.nonZero); + }); +} diff --git a/third_party/test/xml_test.dart b/third_party/test/xml_svg_test.dart similarity index 100% rename from third_party/test/xml_test.dart rename to third_party/test/xml_svg_test.dart From 3ebfd28085bcaac4e6bfef7e5cf6cfb3061eee6f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 15 May 2018 00:32:12 -0400 Subject: [PATCH 056/512] doc updates --- third_party/CHANGELOG.md | 8 ++++++++ third_party/example/main.dart | 3 +-- third_party/lib/flutter_svg.dart | 3 +++ third_party/pubspec.yaml | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 third_party/lib/flutter_svg.dart diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index a110d471fbaf..e9148599ee71 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,13 @@ # CHANGES +## 0.1.3 + +- Add more unit tests and rendering tests (!). +- Add top level flutter_svg.dart. +- Fix bugs found in transform matrix logic for skewX and skewY. +- Minor improvements in handling inheritence for PathFillType. +- Support gradient spread types (TileModes in Flutter). + ## 0.1.2 - Bump to path_drawing 0.2.3 (fix arc defect). diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 174a18539b62..28635d8eee08 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/avd.dart'; -import 'package:flutter_svg/vector_drawable.dart'; -import 'package:flutter_svg/svg.dart'; +import 'package:flutter_svg/flutter_svg.dart'; const List assetNames = const [ 'assets/flutter_logo.svg', diff --git a/third_party/lib/flutter_svg.dart b/third_party/lib/flutter_svg.dart new file mode 100644 index 000000000000..56e63a047132 --- /dev/null +++ b/third_party/lib/flutter_svg.dart @@ -0,0 +1,3 @@ +export 'src/vector_painter.dart'; +export 'svg.dart'; +export 'vector_drawable.dart'; \ No newline at end of file diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index ebc0fb45c963..ca4a17c821e7 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.1.2 +version: 0.1.3 dependencies: path_drawing: ^0.2.3 From 26114430204cb1a19a55c35149f25d9939a07875 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 15 May 2018 00:35:29 -0400 Subject: [PATCH 057/512] format updates --- third_party/lib/flutter_svg.dart | 2 +- third_party/lib/src/avd_parser.dart | 3 ++- third_party/lib/src/utilities/xml.dart | 5 +++-- third_party/test/render_svg_test.dart | 7 ++++--- third_party/tool/gen_golden.dart | 1 - 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/third_party/lib/flutter_svg.dart b/third_party/lib/flutter_svg.dart index 56e63a047132..0c29faec472f 100644 --- a/third_party/lib/flutter_svg.dart +++ b/third_party/lib/flutter_svg.dart @@ -1,3 +1,3 @@ export 'src/vector_painter.dart'; export 'svg.dart'; -export 'vector_drawable.dart'; \ No newline at end of file +export 'vector_drawable.dart'; diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index 3f355b29b136..b13fc3f34517 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -20,7 +20,8 @@ class DrawableAvdPath extends DrawableShape { /// Creates a [DrawableAvdPath] from an XML element factory DrawableAvdPath.fromXml(XmlElement el) { - final String d = getAttribute(el, 'pathData', def: '', namespace: androidNS); + final String d = + getAttribute(el, 'pathData', def: '', namespace: androidNS); final Path path = parseSvgPathData(d); assert(path != null); diff --git a/third_party/lib/src/utilities/xml.dart b/third_party/lib/src/utilities/xml.dart index a9ac2cf398f3..eb3fd2f89b74 100644 --- a/third_party/lib/src/utilities/xml.dart +++ b/third_party/lib/src/utilities/xml.dart @@ -10,11 +10,12 @@ String getAttribute(XmlElement el, String name, if (checkStyle) { final String style = el.getAttribute('style')?.trim(); if (style != '' && style != null) { - // Probably possible to slightly optimize this (e.g. use indexOf instead of split), + // Probably possible to slightly optimize this (e.g. use indexOf instead of split), // but handling potential whitespace will get complicated and this just works. // I also don't feel like writing benchmarks for what is likely a micro-optimization. final List styles = style.split(';'); - raw = styles.firstWhere((String str) => str.trimLeft().startsWith(name + ':'), + raw = styles.firstWhere( + (String str) => str.trimLeft().startsWith(name + ':'), orElse: () => ''); if (raw != '') { diff --git a/third_party/test/render_svg_test.dart b/third_party/test/render_svg_test.dart index 58ee14673f96..c6381f090c1d 100644 --- a/third_party/test/render_svg_test.dart +++ b/third_party/test/render_svg_test.dart @@ -27,14 +27,15 @@ String getSvgAssetName(String goldenFileName) { void main() { test('SVG Rendering matches golden files', () async { for (File goldenFile in getGoldenFileNames()) { - final File svgAssetFile = - new File(getSvgAssetName(goldenFile.path)); + final File svgAssetFile = new File(getSvgAssetName(goldenFile.path)); final Uint8List bytes = await golden.getSvgPngBytes(await svgAssetFile.readAsString()); final Uint8List goldenBytes = await goldenFile.readAsBytes(); - expect(bytes, orderedEquals(goldenBytes), reason: '${goldenFile.path} does not match rendered output of ${svgAssetFile.path}!'); + expect(bytes, orderedEquals(goldenBytes), + reason: + '${goldenFile.path} does not match rendered output of ${svgAssetFile.path}!'); } }); } diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index ee0c74e4d044..7f41bade4409 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -52,7 +52,6 @@ Iterable getSvgFileNames() sync* { } } - String getGoldenFileName(String svgAssetPath) { return svgAssetPath .replaceAll('/assets/', '/golden/') From a5da18c138309a26c01ee6f1781b4836eb1b8e2b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 15 May 2018 00:48:01 -0400 Subject: [PATCH 058/512] single branch travis --- third_party/.travis.yml | 2 +- third_party/pubspec.lock | 2 +- third_party/pubspec.yaml | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/third_party/.travis.yml b/third_party/.travis.yml index 84fb7c548047..4d2ed95541a1 100644 --- a/third_party/.travis.yml +++ b/third_party/.travis.yml @@ -10,7 +10,7 @@ addons: - libstdc++6 - fonts-droid before_script: - - git clone https://github.com/flutter/flutter.git -b dev + - git clone https://github.com/flutter/flutter.git -b dev --single-branch - ./flutter/bin/flutter doctor - gem install coveralls-lcov script: diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 7a0f6c08310e..39b8fdf9106f 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -82,7 +82,7 @@ packages: source: hosted version: "0.1.0-alpha.12" glob: - dependency: "direct dev" + dependency: transitive description: name: glob url: "https://pub.dartlang.org" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index ca4a17c821e7..d02fb425c1a1 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -13,7 +13,6 @@ dependencies: sdk: flutter dev_dependencies: - glob: ^1.1.5 path: ^1.5.1 test: ^0.12.34 flutter_test: From fc264c99ac97295829979bb62ead6cdde12bde60 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 15 May 2018 10:56:36 -0400 Subject: [PATCH 059/512] use ErrorWidget on error --- third_party/lib/vector_drawable.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart index 3f06bf8ce83e..3b63864995a6 100644 --- a/third_party/lib/vector_drawable.dart +++ b/third_party/lib/vector_drawable.dart @@ -25,7 +25,9 @@ class VectorDrawableImage extends StatelessWidget { return new FutureBuilder( future: future, builder: (BuildContext context, AsyncSnapshot snapShot) { - if (snapShot.hasData) { + if (snapShot.hasError) { + return new ErrorWidget(snapShot.error); + } else if (snapShot.hasData) { final CustomPainter painter = new VectorPainter(snapShot.data, clipToViewBox: clipToViewBox); return new RepaintBoundary.wrap( From 7efec9bde6d3ee3fd1fc24a5ddcc30a14f05bbd0 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 15 May 2018 22:08:59 -0400 Subject: [PATCH 060/512] customize error and loading in widget --- third_party/example/main.dart | 13 +++++++++++++ third_party/lib/avd.dart | 28 +++++++++++++++++++++++----- third_party/lib/svg.dart | 28 +++++++++++++++++++++++----- third_party/lib/vector_drawable.dart | 24 +++++++++++++++++++++--- 4 files changed, 80 insertions(+), 13 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 28635d8eee08..0023796a04be 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -3,6 +3,7 @@ import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; const List assetNames = const [ + 'assets/notfound.svg', 'assets/flutter_logo.svg', 'assets/dart.svg', 'assets/simple/group_opacity.svg', @@ -65,6 +66,14 @@ class _MyHomePageState extends State { final List _painters = []; double _dimension; + final ErrorWidgetBuilder customErrorBuilder = (FlutterErrorDetails details) { + print(details); + return const Icon( + Icons.error, + color: Colors.red, + ); + }; + @override void initState() { super.initState(); @@ -75,6 +84,7 @@ class _MyHomePageState extends State { new SvgImage.asset( assetName, new Size(_dimension, _dimension), + errorWidgetBuilder: customErrorBuilder, ), ); } @@ -84,6 +94,9 @@ class _MyHomePageState extends State { new SvgImage.network( uriName, new Size(_dimension, _dimension), + loadingPlaceholderBuilder: (BuildContext context) => new Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator()), ), ); } diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 106342527ac7..abfb02b85366 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -15,22 +15,32 @@ import 'vector_drawable.dart'; /// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. class AvdImage extends VectorDrawableImage { const AvdImage._(Future future, Size size, - {bool clipToViewBox, Key key, PaintLocation paintLocation}) + {bool clipToViewBox, + Key key, + PaintLocation paintLocation, + ErrorWidgetBuilder errorWidgetBuilder, + WidgetBuilder loadingPlaceholderBuilder}) : super(future, size, clipToViewBox: clipToViewBox, key: key, - paintLocation: paintLocation); + paintLocation: paintLocation, + errorWidgetBuilder: errorWidgetBuilder, + loadingPlaceholderBuilder: loadingPlaceholderBuilder); factory AvdImage.fromString(String svg, Size size, {Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background}) { + PaintLocation paintLocation = PaintLocation.Background, + ErrorWidgetBuilder errorWidgetBuilder, + WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( new Future.value(fromAvdString(svg, size)), size, clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, + errorWidgetBuilder: errorWidgetBuilder, + loadingPlaceholderBuilder: loadingPlaceholderBuilder, ); } @@ -39,13 +49,17 @@ class AvdImage extends VectorDrawableImage { AssetBundle bundle, String package, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background}) { + PaintLocation paintLocation = PaintLocation.Background, + ErrorWidgetBuilder errorWidgetBuilder, + WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( loadAsset(assetName, size, bundle: bundle, package: package), size, clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, + errorWidgetBuilder: errorWidgetBuilder, + loadingPlaceholderBuilder: loadingPlaceholderBuilder, ); } @@ -53,13 +67,17 @@ class AvdImage extends VectorDrawableImage { {Map headers, Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background}) { + PaintLocation paintLocation = PaintLocation.Background, + ErrorWidgetBuilder errorWidgetBuilder, + WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( loadNetworkAsset(uri, size), size, clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, + errorWidgetBuilder: errorWidgetBuilder, + loadingPlaceholderBuilder: loadingPlaceholderBuilder, ); } } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index f5dce9d1316b..8881fd0d28ad 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -15,22 +15,32 @@ import 'vector_drawable.dart'; /// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. class SvgImage extends VectorDrawableImage { const SvgImage._(Future future, Size size, - {bool clipToViewBox, Key key, PaintLocation paintLocation}) + {bool clipToViewBox, + Key key, + PaintLocation paintLocation, + ErrorWidgetBuilder errorWidgetBuilder, + WidgetBuilder loadingPlaceholderBuilder}) : super(future, size, clipToViewBox: clipToViewBox, key: key, - paintLocation: paintLocation); + paintLocation: paintLocation, + errorWidgetBuilder: errorWidgetBuilder, + loadingPlaceholderBuilder: loadingPlaceholderBuilder); factory SvgImage.fromString(String svg, Size size, {Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background}) { + PaintLocation paintLocation = PaintLocation.Background, + ErrorWidgetBuilder errorWidgetBuilder, + WidgetBuilder loadingPlaceholderBuilder}) { return new SvgImage._( new Future.value(fromSvgString(svg, size)), size, clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, + errorWidgetBuilder: errorWidgetBuilder, + loadingPlaceholderBuilder: loadingPlaceholderBuilder, ); } @@ -39,13 +49,17 @@ class SvgImage extends VectorDrawableImage { AssetBundle bundle, String package, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background}) { + PaintLocation paintLocation = PaintLocation.Background, + ErrorWidgetBuilder errorWidgetBuilder, + WidgetBuilder loadingPlaceholderBuilder}) { return new SvgImage._( loadAsset(assetName, size, bundle: bundle, package: package), size, clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, + errorWidgetBuilder: errorWidgetBuilder, + loadingPlaceholderBuilder: loadingPlaceholderBuilder, ); } @@ -53,13 +67,17 @@ class SvgImage extends VectorDrawableImage { {Map headers, Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background}) { + PaintLocation paintLocation = PaintLocation.Background, + ErrorWidgetBuilder errorWidgetBuilder, + WidgetBuilder loadingPlaceholderBuilder}) { return new SvgImage._( loadNetworkAsset(uri, size), size, clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, + errorWidgetBuilder: errorWidgetBuilder, + loadingPlaceholderBuilder: loadingPlaceholderBuilder, ); } } diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart index 3b63864995a6..ad6d62b52b37 100644 --- a/third_party/lib/vector_drawable.dart +++ b/third_party/lib/vector_drawable.dart @@ -9,24 +9,40 @@ enum PaintLocation { Foreground, Background } /// Handles rendering [Drawable]s to a canvas. class VectorDrawableImage extends StatelessWidget { + static final WidgetBuilder defaultPlaceholderBuilder = + (BuildContext ctx) => const LimitedBox(); + final Size size; final Future future; final bool clipToViewBox; final PaintLocation paintLocation; + final ErrorWidgetBuilder errorWidgetBuilder; + final WidgetBuilder loadingPlaceholderBuilder; const VectorDrawableImage(this.future, this.size, {this.clipToViewBox = true, Key key, - this.paintLocation = PaintLocation.Background}) + this.paintLocation = PaintLocation.Background, + this.errorWidgetBuilder, + this.loadingPlaceholderBuilder}) : super(key: key); @override Widget build(BuildContext context) { + final ErrorWidgetBuilder localErrorBuilder = + errorWidgetBuilder ?? ErrorWidget.builder; + final WidgetBuilder localPlaceholder = + loadingPlaceholderBuilder ?? defaultPlaceholderBuilder; return new FutureBuilder( future: future, builder: (BuildContext context, AsyncSnapshot snapShot) { if (snapShot.hasError) { - return new ErrorWidget(snapShot.error); + return localErrorBuilder(new FlutterErrorDetails( + context: 'SVG Rendering', + exception: snapShot.error, + library: 'flutter_svg', + stack: StackTrace.current, + )); } else if (snapShot.hasData) { final CustomPainter painter = new VectorPainter(snapShot.data, clipToViewBox: clipToViewBox); @@ -42,7 +58,9 @@ class VectorDrawableImage extends StatelessWidget { ), 0); } - return const LimitedBox(); + return localPlaceholder(context); + + // return const LimitedBox(); }, ); } From be4d50311dda5620d1b51a69a40f6a49ef03ba19 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 16 May 2018 00:59:18 -0400 Subject: [PATCH 061/512] support for radial gradient pct --- third_party/example/main.dart | 13 ++++--- third_party/lib/src/svg/xml_parsers.dart | 45 ++++++++++++++++-------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 0023796a04be..49df675bc047 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -67,11 +67,14 @@ class _MyHomePageState extends State { double _dimension; final ErrorWidgetBuilder customErrorBuilder = (FlutterErrorDetails details) { - print(details); - return const Icon( - Icons.error, - color: Colors.red, - ); + debugPrint(details.toString()); + return new Row(children: const [ + const Icon( + Icons.error, + color: Colors.red, + ), + const Text('Error Loading') + ]); }; @override diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index f5f1d3332426..c411beb78aa9 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -50,9 +50,9 @@ void parseDefs(XmlElement el, Map paintServers) { } } -double _parseDecimalOrPercentage(String val) { +double _parseDecimalOrPercentage(String val, {double multiplier = 1.0}) { if (val.endsWith('%')) { - return double.parse(val.substring(0, val.length - 1)) / 100; + return double.parse(val.substring(0, val.length - 1)) / 100 * multiplier; } else { return double.parse(val); } @@ -117,23 +117,39 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { Paint parseRadialGradient(XmlElement el, Rect bounds) { final String rawCx = getAttribute(el, 'cx', def: '50%'); final String rawCy = getAttribute(el, 'cy', def: '50%'); - final double cx = _parseDecimalOrPercentage(rawCx); - final double cy = _parseDecimalOrPercentage(rawCy); - final double r = _parseDecimalOrPercentage(getAttribute(el, 'r', def: '50%')); - final double fx = - _parseDecimalOrPercentage(getAttribute(el, 'fx', def: rawCx)); - final double fy = - _parseDecimalOrPercentage(getAttribute(el, 'fy', def: rawCy)); + final double cx = _parseDecimalOrPercentage( + rawCx, + multiplier: bounds.width + bounds.left + bounds.left, + ); + final double cy = _parseDecimalOrPercentage( + rawCy, + multiplier: bounds.height + bounds.top + bounds.top, + ); + final double r = _parseDecimalOrPercentage( + getAttribute(el, 'r', def: '50%'), + multiplier: (bounds.width + bounds.height) / 2, + ); + final double fx = _parseDecimalOrPercentage( + getAttribute(el, 'fx', def: rawCx), + multiplier: bounds.width + (bounds.left * 2), + ); + final double fy = _parseDecimalOrPercentage( + getAttribute(el, 'fy', def: rawCy), + multiplier: bounds.height + (bounds.top), + ); final TileMode spreadMethod = parseTileMode(el); - if (fx != cx || fy != cy) { - throw new UnsupportedError( - 'Focal points not supported by this implementation'); + final Offset center = new Offset(cx, cy); + final Offset focal = + (fx != cx || fy != cy) ? new Offset(fx, fy) : new Offset(cx, cy); + + if (focal != center) { + throw new UnsupportedError('Focal points not supported in this version'); } final List stops = el.findElements('stop').toList(); final Gradient gradient = new Gradient.radial( - new Offset(cx, cy), + center, r, stops.map((XmlElement stop) { final String rawOpacity = getAttribute(stop, 'stop-opacity', def: '1'); @@ -145,6 +161,7 @@ Paint parseRadialGradient(XmlElement el, Rect bounds) { return _parseDecimalOrPercentage(rawOffset); }).toList(), spreadMethod, + null, ); return new Paint()..shader = gradient; @@ -276,6 +293,6 @@ Paint parseFill(XmlElement el, Rect bounds, } PathFillType parseFillRule(XmlElement el) { - final String rawFillRule = getAttribute(el, 'fill-rule', def: null); + final String rawFillRule = getAttribute(el, 'fill-rule', def: 'nonzero'); return parseRawFillRule(rawFillRule); } From ecc27bc9aef4816a7791fd0bbb1df66a32e81832 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 16 May 2018 14:15:56 -0400 Subject: [PATCH 062/512] more tests --- third_party/lib/src/vector_painter.dart | 2 +- third_party/pubspec.lock | 7 ++++ third_party/pubspec.yaml | 1 + third_party/test/widget_svg_test.dart | 54 +++++++++++++++++++++++++ third_party/test/xml_svg_test.dart | 27 +++++++++++++ 5 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 third_party/test/widget_svg_test.dart diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index b5fed4d5281a..63dca1523b8e 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -15,7 +15,7 @@ abstract class Drawable { /// Draws the contents or children of this [Drawable] to the `canvas`, using /// the `parentPaint` to optionally override the child's paint. - void draw(Canvas canvas, [DrawableStyle parentStyle]) {} + void draw(Canvas canvas, [DrawableStyle parentStyle]); } @immutable diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 39b8fdf9106f..e73a24504928 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -165,6 +165,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.9.6" + mockito: + dependency: "direct dev" + description: + name: mockito + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" multi_server_socket: dependency: transitive description: diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index d02fb425c1a1..476a2b7c7cd8 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -13,6 +13,7 @@ dependencies: sdk: flutter dev_dependencies: + mockito: ^2.2.3 path: ^1.5.1 test: ^0.12.34 flutter_test: diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart new file mode 100644 index 000000000000..30afd1464f98 --- /dev/null +++ b/third_party/test/widget_svg_test.dart @@ -0,0 +1,54 @@ +import 'dart:async'; +import 'dart:ui'; + +import 'package:flutter/widgets.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mockito/mockito.dart'; + +class MockAssetBundle extends Mock implements AssetBundle {} + +void main() { + const String svg = ''' + + + Example text01 - 'Hello, out there' in blue + + + Hello, out there + + + + +'''; + + testWidgets('SvgImage.fromString', (WidgetTester tester) async { + final GlobalKey key = new GlobalKey(); + await tester.pumpWidget(new SvgImage.fromString( + svg, + const Size(100.0, 100.0), + key: key, + )); + expect(find.byKey(key), findsOneWidget); + }); + + testWidgets('SvgImage.asset', (WidgetTester tester) async { + final MockAssetBundle mockAsset = new MockAssetBundle(); + when(mockAsset.loadString('test.svg')) + .thenAnswer((Invocation inv) => new Future.value(svg)); + + final GlobalKey key = new GlobalKey(); + await tester.pumpWidget(new SvgImage.asset( + 'test.svg', + const Size(100.0, 100.0), + key: key, + bundle: mockAsset, + )); + expect(find.byKey(key), findsOneWidget); + }); +} diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index a3c35f604c30..8a424c8381cc 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -49,8 +49,35 @@ void main() { final XmlElement svgWithWidthHeight = parse('').rootElement; + final XmlElement svgWithNoSizeInfo = parse('').rootElement; expect(parseViewBox(svgWithViewBox), rect); expect(parseViewBox(svgWithViewBoxAndWidthHeight), rect); expect(parseViewBox(svgWithWidthHeight), rect); + expect(parseViewBox(svgWithNoSizeInfo), Rect.zero); + }); + + test('TileMode tests', () { + final XmlElement pad = parse('').rootElement; + final XmlElement reflect = parse('').rootElement; + final XmlElement repeat = parse('').rootElement; + final XmlElement invalid = parse('').rootElement; + + final XmlElement none = parse('').rootElement; + + expect(parseTileMode(pad), TileMode.clamp); + expect(parseTileMode(invalid), TileMode.clamp); + expect(parseTileMode(none), TileMode.clamp); + + expect(parseTileMode(reflect), TileMode.mirror); + expect(parseTileMode(repeat), TileMode.repeated); + }); + + test('@stroke-dashoffset tests', () { + final XmlElement abs = parse('').rootElement; + final XmlElement pct = parse('').rootElement; + + // TODO: DashOffset is completely opaque right now, maybe expose the raw value? + expect(parseDashOffset(abs), isNotNull); + expect(parseDashOffset(pct), isNotNull); }); } From a53bb514e16c2a59ff020e3f38b9902186d9b7d7 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 16 May 2018 21:06:02 -0400 Subject: [PATCH 063/512] add missing gradient to flutter logo --- third_party/assets/flutter_logo.svg | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/third_party/assets/flutter_logo.svg b/third_party/assets/flutter_logo.svg index 75c3e365a007..ec3d9144f352 100644 --- a/third_party/assets/flutter_logo.svg +++ b/third_party/assets/flutter_logo.svg @@ -4,10 +4,17 @@ + + + + - + + + + \ No newline at end of file From 8ebcedbb75d77fd3a3a5a9d053959db4f8ed8ee1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 16 May 2018 21:14:48 -0400 Subject: [PATCH 064/512] update golden image for flutter logo --- third_party/golden/flutter_logo.png | Bin 2763 -> 2788 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/third_party/golden/flutter_logo.png b/third_party/golden/flutter_logo.png index 09b2a54adbbc766655a38c3dd592152848bccee8..697659557c198659378f17bedc60115402cc9595 100644 GIT binary patch literal 2788 zcmaJ@`#;m|8~remys4?gc z9&+9GTaZffyNp?$Cs(it4;lq1@4`>W9fb%A!xJe#7mzFn08o5}gPrHun_q^8PUF3F zTV}^(NneH@_4K<0lZsYRH47BO-E)g6BTDW~`kA(bAFB!bHBY$fdv*_cmN=LmH#N4~ zui&8w*PQjZcKe#fL4{KoW8-t0e+7RV6;)2s86nf}WnmJhy2`%czlSU%x~6ZAZ5koY z#*9UG$qb)+pN`V}L*uH%3Q#`dvnC*S;O;f+!RgG;kxtFo53tAp^Zyb}r`3&fR?oGi zeKeipHBPPtFDU4l%iHd|Cc$ zAtcOWIZe2Wj(CL|d?!dNOuc)o@$CMbI-YJaD03cti>BhE45P!9iRhmhyXrqd_Ksh@ z2xii>44nrU4R%|{txO~Yeja&u(u5DPMn5E)B!izvM@vi+LDtw*hlxBlHvf;RBR=%= z3QElZKlQoQ*fJR$?8whNhG9R=@_XQHE)BE%b>JpNBnjn|9}EylqE^a%>_rj|=V3!C zBussZ*yVs<5gi`4kj`wHa#({+h-GiXIpR4jx(p0^Q71a^79^a0YH5yD9-b=2vd!Xb ztsU_uiO*|@QvWaPdjmxDV~eSGe?jqQ5_c#`{e#Dr%dyHy;>lYi^kd%-Q|s9kwQ;W9~A!@4H zGw4k~Uk@zkQeanR zDb3`IVOHpl2E9jPD6}mS`RB6}9 zL25%ux?7Iebnn~LfCy@#O^s~#Fo(qGl&iU+uJnMQc`6GT0J5wftg z>#$0S6xt)7rwNU)D{|@}bnk;jDrt`)PWp5ge4+~3+FNpXgJPi^P|CM`)^-5zzD&^L zcVX$xA+6Y66`Yj01I|d(z`GC0!;47PtwITum^QffTa|{CX#?jmjQPbU)xk*parsk9 zrxJq6y0o_`KTeWGf}QY*v`t{afB-{_#?liwk+(-x`NcYCK8Zqf{Tc%J;4{e9y5^_E z&Iz3Vr#F0e#}V!)q#-!P3g0 zg-=7mET>d`BHWwgm3HkLY;>hT*^rld4_Pj_nj^+N~6lrrAwsTg%-zHj?6@QA!qg#@Fq-0X{!Pr!>`FLV}# z`UxqIxTpV}F;Yo%-}92x0{)bO$~r8a+_D zyReK3a><`uvL1clO!UTb=h9C7t`Ns^)Hb}7(ycZL2G?`vvNzNBl<@bS=kTk8ezan# zWHFY$A;;0f1>F2q{PSLT#=QX!b%D&07p4@Y6yiQK zR`&Tej@*ChC5?)fnRy=9OVA2GPOG%=6JVgxZi>f=!>w=pcBYEg46m5dssgUMA)Dd3 z+P3P{%WZ}~d^ZR%bkv07Z`7UqT?rEnQ`;k7N~kx%PZ zes+ZV)26vt8Y%S-jqMXU+Aw5*`G}8Rd$e|_FIz&b>`XcI)lzhoY(QP8ncS9P6t|b2| zQpxt|8Z@T1quW68K-+S0)|8zaUeVLHwT%~{yNb(t>p+zh(caOjw(u#6M@BM`E$baB zX1^U*bB5P)H4I$x#B?NC=$IfCl=A*$+Jz3^yJPS|Ve67vv*3Ij#VDSaF=mVlvQZis zEk9r{8}xg5Wm0_FKhbyQ>cV zJfmS4P4LRYBq72kC0bnVkVyKG1@x7s%AaoibK8seyNb(~2R6QskatKs^l0hjdeaMP zhYXB2H4xPu&u<~K|8^i; zBBjrfFcK`|85Tld88KLhgk@OI9(Kl0%I4H|&UVB8h`&DJUbAhdr%3F|!A7T`^=rY8 r^9hyNi;r!Ri*&hWTI&BHJ-=X-)-UHbdgN8hH&uW^b#W-C_+R=T?K<8} literal 2763 zcmaJ@`#;nBAOE-!4CC_avtf@e!v;*<7-@Zz2vBT6G*D zl~67R6H3y$Q0|`<`BKEGsTSY)2hRKPc)eeb=jHW!yx#BkFK^y{cNbkPQ!M}hbeRmg zhaz{chK8DAukx%GDw5I}4;LCx-3Lx9fa)0<^N@yO#cKp{0YEE;Nq0PSuK44~P04Wv&OxlYda+21-_HRUxUOBsGg`r-A= z_G)jRu%sDpY>_1m2eJy6JTpu}eK1bapBHnAc}(NQoyx~7*ZoIaPn=OIcyqe1bLnG` znrZkzZb40sif}0&g}>fC8t(mYU4E?1RN$yY4_ z+^h{MY2={mCnW$55j*|oYbkfniSNX(3aO~Cf})Uao{iGOA-+uu{ULD~{^$Dr#?XhJ z?1L6*4?vePL!tA|6rl?JSOiN*$Hk<&|>xoLv^WQpIHst^1}(@H~EH-v=x_ zf0N`MvK5}MjC2n*hv#cwW$a`DD-5*oS^_0C6FzL)_;2ek7llRM=bT zrmw!e#Ab+y$anG&D<*rgD#mt0w=EAg$HD<#H~;t{ZVMAFXd%__<~^vSg1smHu2zLe zLlupt;x=CqoQ70Clebh!1ABijuhD@>1H9(l;x+sgRUOs)fk8r!fW(a z2&_m7Kn01m(6y8+V-cm#??;_snQd?ytUC^v{l>2wie5fq3KgW2d#5lOtNBik2@)n5 zK|xpavEpN!;cn|0D!0Q|%)h|mAX6K;9qud+9gtsh1c|xHDz|llM3{+GTQw33TK;gS zR^gOH0*GbZZLP`WMhpc+LqOKrPVahW2Q*B&atLI1%q0ao)4)kVhDxNoBsz1|B!K{B zVfuAVO{m~E6$BMPQq@=8h9Db>WrqTqKBXwBdLa~9%qnE#j z?{QGU#kE!D_$k*}(7)Ey*BGE|T{s*y>Aw%XXizHs3K6aCb2x{A^)t~OKp z;gz9~VwW0|6z9NUJyr+V%GiJW2u0iE;=0V^a%Z#iD+fAURhFLR8CvJZB;c%ijX*XU z`;T05byTQ}HX;itzRhRq|9<{eowtt+I8lL8j~&@!gRIcS(W^2gUIZEVoeJD#h{hR` z46zHyreWD81W6X2=UU*=$Mn>V^fOOu;EBi}26W@D*<_ClLrB+l9)0&kye66O@?2 zWZ)SakSR`iJaD5K$lT0N=BgAV?Cftzm!30YA1B)9SDY~2dSeoHz1muLn^$2i{C3{p z#h2NLQ@4TmWB1qhk;Ia$&2TNtIGS#lG!y^&C&7cC? zDSHu*MiQ*(G;qWT`{dpn*MTfJJ;31=#l**qV4!Fe$MVH!mwN5R{x6slo2Gmk+dTTMvC&(9?835J)Aox`CxUk4axUM)Zk)s4&nejFJOXac9k6n}u|;{BWW~6ot?O&MWZGBkA6FlG{Y0g1{93DLDL5{@$4=`^g`6I158mdt}SP3%)wo>KfMS@?VW zJ!ZQs>9q~}6@?RbXdWT^r0;4H0##iyG^!fdM74f8YU{#>cO@j6qJc?}Df2odQ`$P5 z+Oz5BIJdtY2(>7?w6LD^pjBRGZl05|Ek!i^AZ4XRj`y9L-sF;eVh7iIM@Hjt+{**b zW+^R`O6@d7o7Y%t92L%i zO@hk?VwZZoL;}fPMUR;SxKUYWdPi;0}pX>Vos^Q{MKoUjC+6e%M!! z9;=T(TRg|m5POv1yi%v5!4xg{@y+LN=PkTtl*F&&#yMu)0dU`rv4s2sf|vk=1QDxE=P{1L!5fD%3K}n%#UtONnD Date: Thu, 17 May 2018 09:15:20 -0400 Subject: [PATCH 065/512] more tests --- third_party/lib/svg.dart | 5 ++- third_party/test/widget_svg_test.dart | 65 +++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 8881fd0d28ad..e2a2e812daed 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -128,9 +128,12 @@ Future loadNetworkAsset(String url, Size size) async { final Uri uri = Uri.base.resolve(url); final HttpClientRequest request = await _httpClient.getUrl(uri); final HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.OK) + + if (response.statusCode != HttpStatus.OK) { throw new HttpException('Could not get network SVG asset', uri: uri); + } final String rawSvg = await _consolidateHttpClientResponse(response); + return fromSvgString(rawSvg, size); } diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 30afd1464f98..4f13d23a0d86 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -1,4 +1,6 @@ import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; import 'dart:ui'; import 'package:flutter/widgets.dart'; @@ -7,8 +9,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:mockito/mockito.dart'; -class MockAssetBundle extends Mock implements AssetBundle {} - void main() { const String svg = ''' new Future.value(svg)); + .thenAnswer((_) => new Future.value(svg)); final GlobalKey key = new GlobalKey(); await tester.pumpWidget(new SvgImage.asset( @@ -51,4 +51,63 @@ void main() { )); expect(find.byKey(key), findsOneWidget); }); + + final MockHttpClient mockHttpClient = new MockHttpClient(); + final MockHttpClientRequest mockRequest = new MockHttpClientRequest(); + final MockHttpClientResponse mockResponse = new MockHttpClientResponse(); + + when(mockHttpClient.getUrl(typed(any))) + .thenAnswer((_) => new Future.value(mockRequest)); + + when(mockRequest.close()).thenAnswer( + (_) => new Future.value(mockResponse)); + + when(mockResponse.transform(typed(any))) + .thenAnswer((_) => new Stream.fromIterable([svg])); + when(mockResponse.listen(typed(any), + onDone: typed(any, named: 'onDone'), + onError: typed(any, named: 'onError'), + cancelOnError: typed(any, named: 'cancelOnError'))) + .thenAnswer((Invocation invocation) { + final void Function(String) onData = invocation.positionalArguments[0]; + final void Function(Object) onError = invocation.namedArguments[#onError]; + final void Function() onDone = invocation.namedArguments[#onDone]; + final bool cancelOnError = invocation.namedArguments[#cancelOnError]; + + return new Stream.fromIterable([svg]).listen( + onData, + onDone: onDone, + onError: onError, + cancelOnError: cancelOnError, + ); + }); + + testWidgets('SvgImage.network', (WidgetTester tester) async { + HttpOverrides.runZoned(() async { + when(mockResponse.statusCode).thenReturn(200); + final GlobalKey key = new GlobalKey(); + await tester.pumpWidget(new SvgImage.network( + 'test.svg', + const Size(100.0, 100.0), + key: key, + )); + expect(find.byKey(key), findsOneWidget); + }, createHttpClient: (SecurityContext c) => mockHttpClient); + }); + + test('loadNetworkAsset HTTP exception', () { + HttpOverrides.runZoned(() { + when(mockResponse.statusCode).thenReturn(400); + expect(() => loadNetworkAsset('test.svg', const Size(100.0, 100.0)), + throwsA(const isInstanceOf())); + }, createHttpClient: (SecurityContext c) => mockHttpClient); + }); } + +class MockAssetBundle extends Mock implements AssetBundle {} + +class MockHttpClient extends Mock implements HttpClient {} + +class MockHttpClientRequest extends Mock implements HttpClientRequest {} + +class MockHttpClientResponse extends Mock implements HttpClientResponse {} From 03d0bf593a395cab1d4bf84bd633cf970837dc6e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 17 May 2018 10:06:12 -0400 Subject: [PATCH 066/512] README and docs, formatting --- third_party/lib/src/vector_painter.dart | 32 ++++++++++++++- third_party/lib/svg.dart | 19 +++++++-- third_party/lib/vector_drawable.dart | 53 ++++++++++++++++++++----- third_party/test/widget_svg_test.dart | 2 +- third_party/test/xml_svg_test.dart | 22 ++++++---- 5 files changed, 104 insertions(+), 24 deletions(-) diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 63dca1523b8e..d69b03d90aca 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -18,6 +18,9 @@ abstract class Drawable { void draw(Canvas canvas, [DrawableStyle parentStyle]); } +/// Styling information for vector drawing. +/// +/// Contains [Paint], [Path], dashing, transform, and text styling information. @immutable class DrawableStyle { /// This should be used where 'stroke' or 'fill' are 'none'. @@ -34,13 +37,29 @@ class DrawableStyle { static final CircularIntervalList emptyDashArray = new CircularIntervalList(const []); + /// If not `null` and not `identical` with [emptyPaint], will result in a stroke + /// for the rendered [DrawableShape]. Drawn __after__ the [fill]. final Paint stroke; + + /// The dashing array to use for the [stroke], if any. final CircularIntervalList dashArray; + + /// The [DashOffset] to use for where to begin the [dashArray]. final DashOffset dashOffset; + + /// If not `null` and not `identical` with [emptyPaint], will result in a fill + /// for the rendered [DrawableShape]. Drawn __before__ the [stroke]. final Paint fill; + + /// The 4x4 matrix ([Matrix4]) for a transform, if any. final Float64List transform; + final TextStyle textStyle; + + /// The fill rule to use for this path. final PathFillType pathFillType; + + /// Controls inheriting opacity. Will be averaged with child opacity. final double groupOpacity; const DrawableStyle( @@ -54,7 +73,7 @@ class DrawableStyle { this.groupOpacity}); /// Creates a new [DrawableStyle] if `other` is not null, filling in any null properties on - /// this with the properties from other. + /// this with the properties from other (except [groupOpacity], which is averaged). /// /// If `other` is null, returns this. DrawableStyle mergeAndBlend(DrawableStyle other) { @@ -90,6 +109,9 @@ class DrawableStyle { return ret; } + /// Averages [back] and [front]. If either is null, returns the other. + /// + /// Result is null if both [back] and [front] are null. static double mergeOpacity(double back, double front) { if (back == null) { return front; @@ -101,6 +123,7 @@ class DrawableStyle { } } +// WIP class DrawableText implements Drawable { final Offset offset; final DrawableStyle style; @@ -138,8 +161,11 @@ class DrawableRoot implements Drawable { /// The actual child or group to draw. final List children; + /// Contains [Paint]s that are used by multiple children, e.g. + /// gradient shaders that are referenced by an identifier. final Map paintServers; + /// The [DrawableStyle] for inheritence. final DrawableStyle style; const DrawableRoot( @@ -188,7 +214,9 @@ class DrawableRoot implements Drawable { } } -/// Represents an element that is not rendered and has no chidlren. +/// Represents an element that is not rendered and has no chidlren, e.g. +/// a descriptive element. +// TODO: tie some of this into semantics/accessibility class DrawableNoop implements Drawable { final String name; const DrawableNoop(this.name); diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index e2a2e812daed..e7cb72924459 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -17,11 +17,13 @@ class SvgImage extends VectorDrawableImage { const SvgImage._(Future future, Size size, {bool clipToViewBox, Key key, + Widget child, PaintLocation paintLocation, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) : super(future, size, clipToViewBox: clipToViewBox, + child: child, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, @@ -31,12 +33,14 @@ class SvgImage extends VectorDrawableImage { {Key key, bool clipToViewBox = true, PaintLocation paintLocation = PaintLocation.Background, + Widget child, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new SvgImage._( new Future.value(fromSvgString(svg, size)), size, clipToViewBox: clipToViewBox, + child: child, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, @@ -44,18 +48,21 @@ class SvgImage extends VectorDrawableImage { ); } + /// Creates an [SvgImage] from a bundled asset (possibly from a [package]). factory SvgImage.asset(String assetName, Size size, {Key key, AssetBundle bundle, String package, bool clipToViewBox = true, PaintLocation paintLocation = PaintLocation.Background, + Widget child, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new SvgImage._( loadAsset(assetName, size, bundle: bundle, package: package), size, clipToViewBox: clipToViewBox, + child: child, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, @@ -63,10 +70,12 @@ class SvgImage extends VectorDrawableImage { ); } + /// Creates an [SvgImage] from a HTTP [uri]. factory SvgImage.network(String uri, Size size, {Map headers, Key key, bool clipToViewBox = true, + Widget child, PaintLocation paintLocation = PaintLocation.Background, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { @@ -74,6 +83,7 @@ class SvgImage extends VectorDrawableImage { loadNetworkAsset(uri, size), size, clipToViewBox: clipToViewBox, + child: child, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, @@ -82,7 +92,8 @@ class SvgImage extends VectorDrawableImage { } } -/// Creates a [DrawableRoot] from a string of SVG data. +/// Creates a [DrawableRoot] from a string of SVG data. [size] specifies the +/// size of the coordinate space to draw to. DrawableRoot fromSvgString(String rawSvg, Size size) { final XmlElement svg = xml.parse(rawSvg).rootElement; final Rect viewBox = parseViewBox(svg); @@ -111,7 +122,8 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { ); } -/// Creates a [DrawableRoot] from a bundled asset. +/// Creates a [DrawableRoot] from a bundled asset. [size] specifies the size +/// of the coordinate space to draw to. Future loadAsset(String assetName, Size size, {AssetBundle bundle, String package}) async { bundle ??= rootBundle; @@ -124,12 +136,13 @@ Future loadAsset(String assetName, Size size, final HttpClient _httpClient = new HttpClient(); /// Creates a [DrawableRoot] from a network asset with an HTTP get request. +/// [size] specifies the size of the coordinate space to draw to. Future loadNetworkAsset(String url, Size size) async { final Uri uri = Uri.base.resolve(url); final HttpClientRequest request = await _httpClient.getUrl(uri); final HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.OK) { + if (response.statusCode != HttpStatus.OK) { throw new HttpException('Could not get network SVG asset', uri: uri); } final String rawSvg = await _consolidateHttpClientResponse(response); diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart index ad6d62b52b37..a9dbdd642e11 100644 --- a/third_party/lib/vector_drawable.dart +++ b/third_party/lib/vector_drawable.dart @@ -7,24 +7,55 @@ import 'src/vector_painter.dart'; enum PaintLocation { Foreground, Background } -/// Handles rendering [Drawable]s to a canvas. +/// Handles rendering the [DrawableRoot] from `future` to a [Canvas]. +/// +/// To control the coordinate space, use the `size` parameter. In most +/// contexts, you should prefer keeping `clipToViewBox` as true to avoid +/// potentially drawing outside the bounds of the canvas. By default, +/// this will draw to the background (meaning the child widget will be +/// rendered after drawing). You can change that by specifying +/// `PaintLocation.Foreground`. +/// +/// By default, a [LimitedBox] will be rendered while the `future` is resolving. +/// This can be replaced by specifying `loadingPlaceholderBuilder`, and is +/// especially useful if you're loading a network asset. +/// +/// By default, an [ErrorWidget] will be rendered if an error occurs. This +/// can be replace with a custom [ErrorWidgetBuilder] to taste. class VectorDrawableImage extends StatelessWidget { static final WidgetBuilder defaultPlaceholderBuilder = (BuildContext ctx) => const LimitedBox(); + /// The size of the coordinate space to render this image in. final Size size; + + /// The [Future] that resolves the drawing content. final Future future; + + /// Whether to allow drawing outside of the canvas or not. Defaults to + /// true. final bool clipToViewBox; + + /// Whether to draw before or after child content. Defaults to background + /// (before). final PaintLocation paintLocation; + + /// [ErrorWidgetBuilder] to specify what to render if an exception is thrown. final ErrorWidgetBuilder errorWidgetBuilder; + + /// [WidgetBuilder] to use while the [future] is resolving. final WidgetBuilder loadingPlaceholderBuilder; + /// Child content for this widget. + final Widget child; + const VectorDrawableImage(this.future, this.size, {this.clipToViewBox = true, Key key, this.paintLocation = PaintLocation.Background, this.errorWidgetBuilder, - this.loadingPlaceholderBuilder}) + this.loadingPlaceholderBuilder, + this.child}) : super(key: key); @override @@ -48,14 +79,16 @@ class VectorDrawableImage extends StatelessWidget { new VectorPainter(snapShot.data, clipToViewBox: clipToViewBox); return new RepaintBoundary.wrap( CustomPaint( - painter: - paintLocation == PaintLocation.Background ? painter : null, - foregroundPainter: - paintLocation == PaintLocation.Foreground ? painter : null, - size: size, - isComplex: true, - willChange: false, - ), + painter: paintLocation == PaintLocation.Background + ? painter + : null, + foregroundPainter: paintLocation == PaintLocation.Foreground + ? painter + : null, + size: size, + isComplex: true, + willChange: false, + child: child), 0); } return localPlaceholder(context); diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 4f13d23a0d86..33b2cd00a71b 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:convert'; import 'dart:io'; import 'dart:ui'; @@ -95,6 +94,7 @@ void main() { }, createHttpClient: (SecurityContext c) => mockHttpClient); }); + // TODO: Why isn't this working when I just use SvgImage.network? test('loadNetworkAsset HTTP exception', () { HttpOverrides.runZoned(() { when(mockResponse.statusCode).thenReturn(400); diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index 8a424c8381cc..c474d1d6f5f3 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -57,13 +57,17 @@ void main() { }); test('TileMode tests', () { - final XmlElement pad = parse('').rootElement; - final XmlElement reflect = parse('').rootElement; - final XmlElement repeat = parse('').rootElement; - final XmlElement invalid = parse('').rootElement; - + final XmlElement pad = + parse('').rootElement; + final XmlElement reflect = + parse('').rootElement; + final XmlElement repeat = + parse('').rootElement; + final XmlElement invalid = + parse('').rootElement; + final XmlElement none = parse('').rootElement; - + expect(parseTileMode(pad), TileMode.clamp); expect(parseTileMode(invalid), TileMode.clamp); expect(parseTileMode(none), TileMode.clamp); @@ -73,8 +77,10 @@ void main() { }); test('@stroke-dashoffset tests', () { - final XmlElement abs = parse('').rootElement; - final XmlElement pct = parse('').rootElement; + final XmlElement abs = + parse('').rootElement; + final XmlElement pct = + parse('').rootElement; // TODO: DashOffset is completely opaque right now, maybe expose the raw value? expect(parseDashOffset(abs), isNotNull); From 3ccdc13431a6d87c1828588f91865d4be8e235d9 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 17 May 2018 10:08:43 -0400 Subject: [PATCH 067/512] bump ver --- third_party/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 476a2b7c7cd8..b213c7d1333f 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.1.3 +version: 0.1.4 dependencies: path_drawing: ^0.2.3 From d64ee3d10ad713877e074771fc12de652eeb4b5e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 17 May 2018 10:12:37 -0400 Subject: [PATCH 068/512] CHANGELOG updates... --- third_party/CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index e9148599ee71..a1df18dc6252 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,13 @@ # CHANGES +## 0.1.4 + +- Fix bugs in `` percentage handling. +- Add error widget on error. +- Add ability to specify error/placeholder widgets. +- Minor improvement on flutter logo SVG (add missing gradient). +- Improve docs, unit tests. + ## 0.1.3 - Add more unit tests and rendering tests (!). From 7a469dfeec528ef4b99f60e396f4853b3889ff79 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 19 May 2018 14:15:07 -0400 Subject: [PATCH 069/512] Refactor in prep for clipPath --- third_party/lib/avd.dart | 2 +- third_party/lib/src/avd_parser.dart | 4 +- third_party/lib/src/svg/xml_parsers.dart | 183 +++++++++++++---------- third_party/lib/src/svg_parser.dart | 90 +++++------ third_party/lib/src/vector_painter.dart | 61 +++++++- third_party/lib/svg.dart | 11 +- third_party/pubspec.lock | 2 +- 7 files changed, 213 insertions(+), 140 deletions(-) diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index abfb02b85366..d92b87ebd6ef 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -94,7 +94,7 @@ DrawableRoot fromAvdString(String rawSvg, Size size) { Offset.zero, new Offset(size.width, size.height)))) .toList(); // todo : style on root - return new DrawableRoot(viewBox, children, {}, null); + return new DrawableRoot(viewBox, children, new DrawableDefinitionServer(), null); } /// Creates a [DrawableRoot] from a bundled asset. diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index b13fc3f34517..dcdef0f3a0bc 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -10,8 +10,8 @@ import 'vector_painter.dart'; class DrawableAvdRoot extends DrawableRoot { const DrawableAvdRoot(Rect viewBox, List children, - Map paintServers, DrawableStyle style) - : super(viewBox, children, paintServers, style); + DrawableDefinitionServer definitions, DrawableStyle style) + : super(viewBox, children, definitions, style); } /// An SVG Shape element that will be drawn to the canvas. diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index c411beb78aa9..f07550dd9ee3 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -38,13 +38,16 @@ Rect parseViewBox(XmlElement svg) { ); } +String buildUrlIri(XmlElement def) => 'url(#${getAttribute(def, 'id')})'; + /// Parses a element, extracting and (TODO) elements into the `paintServers` map. -void parseDefs(XmlElement el, Map paintServers) { +void parseDefs(XmlElement el, DrawableDefinitionServer definitions) { for (XmlNode def in el.children) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { - paintServers['url(#${getAttribute(def, 'id')})'] = - (Rect bounds) => parseGradient(def, bounds); + definitions.addPaintServer(buildUrlIri(def), parseGradient(def)); + } else if (def.name.local == 'clipPath') { + definitions.addClipPath(buildUrlIri(def), parseClipPath(def)); } } } @@ -72,8 +75,20 @@ TileMode parseTileMode(XmlElement el) { } } +void parseStops( + List stops, List colors, List offsets) { + for (int i = 0; i < stops.length; i++) { + final String rawOpacity = getAttribute(stops[i], 'stop-opacity', def: '1'); + colors[i] = parseColor(getAttribute(stops[i], 'stop-color')) + .withOpacity(double.parse(rawOpacity)); + + final String rawOffset = getAttribute(stops[i], 'offset'); + offsets[i] = _parseDecimalOrPercentage(rawOffset); + } +} + /// Parses an SVG element into a [Paint]. -Paint parseLinearGradient(XmlElement el, Rect bounds) { +PaintServer parseLinearGradient(XmlElement el) { final double x1 = _parseDecimalOrPercentage(getAttribute(el, 'x1', def: '0%')); final double x2 = @@ -84,95 +99,99 @@ Paint parseLinearGradient(XmlElement el, Rect bounds) { _parseDecimalOrPercentage(getAttribute(el, 'y2', def: '0%')); final TileMode spreadMethod = parseTileMode(el); - - final Offset from = new Offset( - bounds.left + (bounds.width * x1), - bounds.left + (bounds.height * y1), - ); - final Offset to = new Offset( - bounds.left + (bounds.width * x2), - bounds.left + (bounds.height * y2), - ); - final List stops = el.findElements('stop').toList(); - final Gradient gradient = new Gradient.linear( - from, - to, - stops.map((XmlElement stop) { - final String rawOpacity = getAttribute(stop, 'stop-opacity', def: '1'); - return parseColor(getAttribute(stop, 'stop-color')) - .withOpacity(double.parse(rawOpacity)); - }).toList(), - stops.map((XmlElement stop) { - final String rawOffset = getAttribute(stop, 'offset'); - return _parseDecimalOrPercentage(rawOffset); - }).toList(), - spreadMethod, - ); - - return new Paint()..shader = gradient; + final List colors = new List(stops.length); + final List offsets = new List(stops.length); + + parseStops(stops, colors, offsets); + + return (Rect bounds) { + final Offset from = new Offset( + bounds.left + (bounds.width * x1), + bounds.left + (bounds.height * y1), + ); + final Offset to = new Offset( + bounds.left + (bounds.width * x2), + bounds.left + (bounds.height * y2), + ); + + final Gradient gradient = new Gradient.linear( + from, + to, + colors, + offsets, + spreadMethod, + ); + + return new Paint()..shader = gradient; + }; } /// Parses a into a [Paint]. -Paint parseRadialGradient(XmlElement el, Rect bounds) { +PaintServer parseRadialGradient(XmlElement el) { final String rawCx = getAttribute(el, 'cx', def: '50%'); final String rawCy = getAttribute(el, 'cy', def: '50%'); - final double cx = _parseDecimalOrPercentage( - rawCx, - multiplier: bounds.width + bounds.left + bounds.left, - ); - final double cy = _parseDecimalOrPercentage( - rawCy, - multiplier: bounds.height + bounds.top + bounds.top, - ); - final double r = _parseDecimalOrPercentage( - getAttribute(el, 'r', def: '50%'), - multiplier: (bounds.width + bounds.height) / 2, - ); - final double fx = _parseDecimalOrPercentage( - getAttribute(el, 'fx', def: rawCx), - multiplier: bounds.width + (bounds.left * 2), - ); - final double fy = _parseDecimalOrPercentage( - getAttribute(el, 'fy', def: rawCy), - multiplier: bounds.height + (bounds.top), - ); - final TileMode spreadMethod = parseTileMode(el); - final Offset center = new Offset(cx, cy); - final Offset focal = - (fx != cx || fy != cy) ? new Offset(fx, fy) : new Offset(cx, cy); - - if (focal != center) { - throw new UnsupportedError('Focal points not supported in this version'); - } final List stops = el.findElements('stop').toList(); - final Gradient gradient = new Gradient.radial( - center, - r, - stops.map((XmlElement stop) { - final String rawOpacity = getAttribute(stop, 'stop-opacity', def: '1'); - return parseColor(getAttribute(stop, 'stop-color')) - .withOpacity(double.parse(rawOpacity)); - }).toList(), - stops.map((XmlElement stop) { - final String rawOffset = getAttribute(stop, 'offset'); - return _parseDecimalOrPercentage(rawOffset); - }).toList(), - spreadMethod, - null, - ); - return new Paint()..shader = gradient; + final List colors = new List(stops.length); + final List offsets = new List(stops.length); + parseStops(stops, colors, offsets); + + return (Rect bounds) { + final double cx = _parseDecimalOrPercentage( + rawCx, + multiplier: bounds.width + bounds.left + bounds.left, + ); + final double cy = _parseDecimalOrPercentage( + rawCy, + multiplier: bounds.height + bounds.top + bounds.top, + ); + final double r = _parseDecimalOrPercentage( + getAttribute(el, 'r', def: '50%'), + multiplier: (bounds.width + bounds.height) / 2, + ); + final double fx = _parseDecimalOrPercentage( + getAttribute(el, 'fx', def: rawCx), + multiplier: bounds.width + (bounds.left * 2), + ); + final double fy = _parseDecimalOrPercentage( + getAttribute(el, 'fy', def: rawCy), + multiplier: bounds.height + (bounds.top), + ); + + final Offset center = new Offset(cx, cy); + final Offset focal = + (fx != cx || fy != cy) ? new Offset(fx, fy) : new Offset(cx, cy); + + if (focal != center) { + throw new UnsupportedError('Focal points not supported in this version'); + } + + final Gradient gradient = new Gradient.radial( + center, + r, + colors, + offsets, + spreadMethod, + null, + ); + + return new Paint()..shader = gradient; + }; +} + +Path parseClipPath(XmlElement el) { + return new Path(); } /// Parses a or into a [Paint]. -Paint parseGradient(XmlElement el, Rect bounds) { +PaintServer parseGradient(XmlElement el) { if (el.name.local == 'linearGradient') { - return parseLinearGradient(el, bounds); + return parseLinearGradient(el); } else if (el.name.local == 'radialGradient') { - return parseRadialGradient(el, bounds); + return parseRadialGradient(el); } throw new StateError('Unknown gradient type ${el.name.local}'); } @@ -221,7 +240,7 @@ double parseOpacity(XmlElement el) { /// Parses a @stroke attribute into a [Paint]. Paint parseStroke( - XmlElement el, Rect bounds, Map paintServers) { + XmlElement el, Rect bounds, DrawableDefinitionServer definitions) { final String rawStroke = getAttribute(el, 'stroke'); if (rawStroke == '') { return null; @@ -230,7 +249,7 @@ Paint parseStroke( } if (rawStroke.startsWith('url')) { - return paintServers[rawStroke](bounds); + return definitions.getPaint(rawStroke, bounds); } final String rawOpacity = getAttribute(el, 'stroke-opacity'); @@ -265,7 +284,7 @@ Paint parseStroke( } Paint parseFill(XmlElement el, Rect bounds, - Map paintServers, Color defaultFillIfNotSpecified) { + DrawableDefinitionServer definitions, Color defaultFillIfNotSpecified) { final String rawFill = getAttribute(el, 'fill'); if (rawFill == '') { if (defaultFillIfNotSpecified == null) { @@ -277,7 +296,7 @@ Paint parseFill(XmlElement el, Rect bounds, } if (rawFill.startsWith('url')) { - return paintServers[rawFill](bounds); + return definitions.getPaint(rawFill, bounds); } final String rawOpacity = getAttribute(el, 'fill-opacity'); diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 4ac5dafa6347..b29e81f74a83 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -11,30 +11,30 @@ import 'utilities/xml.dart'; import 'vector_painter.dart'; typedef DrawableSvgShape SvgShapeFactory(XmlElement el, - Map paintServers, DrawableStyle parentStyle); + DrawableDefinitionServer definitions, DrawableStyle parentStyle); final Map _shapes = { - 'circle': (XmlElement el, Map paintServers, + 'circle': (XmlElement el, DrawableDefinitionServer definitions, DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgCircle(el, paintServers, parentStyle), - 'path': (XmlElement el, Map paintServers, + new DrawableSvgShape.fromSvgCircle(el, definitions, parentStyle), + 'path': (XmlElement el, DrawableDefinitionServer definitions, DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgPath(el, paintServers, parentStyle), - 'rect': (XmlElement el, Map paintServers, + new DrawableSvgShape.fromSvgPath(el, definitions, parentStyle), + 'rect': (XmlElement el, DrawableDefinitionServer definitions, DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgRect(el, paintServers, parentStyle), - 'polygon': (XmlElement el, Map paintServers, + new DrawableSvgShape.fromSvgRect(el, definitions, parentStyle), + 'polygon': (XmlElement el, DrawableDefinitionServer definitions, DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgPolygonOrLine(el, paintServers, parentStyle), - 'polyline': (XmlElement el, Map paintServers, + new DrawableSvgShape.fromSvgPolygonOrLine(el, definitions, parentStyle), + 'polyline': (XmlElement el, DrawableDefinitionServer definitions, DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgPolygonOrLine(el, paintServers, parentStyle), - 'ellipse': (XmlElement el, Map paintServers, + new DrawableSvgShape.fromSvgPolygonOrLine(el, definitions, parentStyle), + 'ellipse': (XmlElement el, DrawableDefinitionServer definitions, DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgEllipse(el, paintServers, parentStyle), - 'line': (XmlElement el, Map paintServers, + new DrawableSvgShape.fromSvgEllipse(el, definitions, parentStyle), + 'line': (XmlElement el, DrawableDefinitionServer definitions, DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgLine(el, paintServers, parentStyle), + new DrawableSvgShape.fromSvgLine(el, definitions, parentStyle), }; /// An SVG Shape element that will be drawn to the canvas. @@ -43,7 +43,7 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgCircle(XmlElement el, - Map paintServers, DrawableStyle parentStyle) { + DrawableDefinitionServer definitions, DrawableStyle parentStyle) { final double cx = double.parse(getAttribute(el, 'cx', def: '0')); final double cy = double.parse(getAttribute(el, 'cy', def: '0')); final double r = double.parse(getAttribute(el, 'r', def: '0')); @@ -51,21 +51,21 @@ class DrawableSvgShape extends DrawableShape { new Rect.fromCircle(center: new Offset(cx, cy), radius: r); final Path path = new Path()..addOval(oval); - return _createDrawable(path, paintServers, el, parentStyle); + return _createDrawable(path, definitions, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgPath(XmlElement el, - Map paintServers, DrawableStyle parentStyle) { + DrawableDefinitionServer definitions, DrawableStyle parentStyle) { final String d = getAttribute(el, 'd'); final Path path = parseSvgPathData(d); - return _createDrawable(path, paintServers, el, parentStyle); + return _createDrawable(path, definitions, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgRect(XmlElement el, - Map paintServers, DrawableStyle parentStyle) { + DrawableDefinitionServer definitions, DrawableStyle parentStyle) { final double x = double.parse(getAttribute(el, 'x', def: '0')); final double y = double.parse(getAttribute(el, 'y', def: '0')); final double w = double.parse(getAttribute(el, 'width', def: '0')); @@ -82,31 +82,31 @@ class DrawableSvgShape extends DrawableShape { return _createDrawable( new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)), - paintServers, + definitions, el, parentStyle, ); } final Path path = new Path()..addRect(rect); - return _createDrawable(path, paintServers, el, parentStyle); + return _createDrawable(path, definitions, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG or element. factory DrawableSvgShape.fromSvgPolygonOrLine(XmlElement el, - Map paintServers, DrawableStyle parentStyle) { + DrawableDefinitionServer definitions, DrawableStyle parentStyle) { final String points = getAttribute(el, 'points'); if (points == '') { - return _createDrawable(null, paintServers, el, parentStyle); + return _createDrawable(null, definitions, el, parentStyle); } final Path path = parseSvgPathData('M' + points + 'z'); - return _createDrawable(path, paintServers, el, parentStyle); + return _createDrawable(path, definitions, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgEllipse(XmlElement el, - Map paintServers, DrawableStyle parentStyle) { + DrawableDefinitionServer definitions, DrawableStyle parentStyle) { final double cx = double.parse(getAttribute(el, 'cx', def: '0')); final double cy = double.parse(getAttribute(el, 'cy', def: '0')); final double rx = double.parse(getAttribute(el, 'rx', def: '0')); @@ -115,12 +115,12 @@ class DrawableSvgShape extends DrawableShape { final Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); return _createDrawable( - new Path()..addOval(r), paintServers, el, parentStyle); + new Path()..addOval(r), definitions, el, parentStyle); } /// Creates a [DrawableSvgShape] from an SVG element. factory DrawableSvgShape.fromSvgLine(XmlElement el, - Map paintServers, DrawableStyle parentStyle) { + DrawableDefinitionServer definitions, DrawableStyle parentStyle) { final double x1 = double.parse(getAttribute(el, 'x1', def: '0')); final double x2 = double.parse(getAttribute(el, 'x2', def: '0')); final double y1 = double.parse(getAttribute(el, 'y1', def: '0')); @@ -129,7 +129,7 @@ class DrawableSvgShape extends DrawableShape { final Path path = new Path() ..moveTo(x1, y1) ..lineTo(x2, y2); - return _createDrawable(path, paintServers, el, parentStyle); + return _createDrawable(path, definitions, el, parentStyle); } /// Applies the transformation in the @transform attribute to the path. @@ -149,7 +149,7 @@ class DrawableSvgShape extends DrawableShape { static DrawableSvgShape _createDrawable( Path path, - Map paintServers, + DrawableDefinitionServer definitions, XmlElement el, DrawableStyle parentStyle) { assert(path != null); @@ -158,7 +158,7 @@ class DrawableSvgShape extends DrawableShape { return new DrawableSvgShape( transformPath(path, el), - parseStyle(el, paintServers, path.getBounds(), + parseStyle(el, definitions, path.getBounds(), defaultFillIfNotSpecified: defaultFill), ); } @@ -167,22 +167,22 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [Drawable] from an SVG or shape element. Also handles parsing and gradients. /// /// If an unsupported element is encountered, it will be created as a [DrawableNoop]. -Drawable parseSvgElement(XmlElement el, Map paintServers, +Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, Rect bounds, DrawableStyle parentStyle) { final SvgShapeFactory shapeFn = _shapes[el.name.local]; if (shapeFn != null) { - return shapeFn(el, paintServers, parentStyle); + return shapeFn(el, definitions, parentStyle); } else if (el.name.local == 'defs') { - parseDefs(el, paintServers); + parseDefs(el, definitions); return new DrawableNoop(el.name.local); } else if (el.name.local.endsWith('Gradient')) { - paintServers['url(#${getAttribute(el, 'id')})'] = - (Rect bounds) => parseGradient(el, bounds); + definitions.addPaintServer( + 'url(#${getAttribute(el, 'id')})', parseGradient(el)); return new DrawableNoop(el.name.local); } else if (el.name.local == 'g' || el.name.local == 'a') { - return parseSvgGroup(el, paintServers, bounds); + return parseSvgGroup(el, definitions, bounds); } else if (el.name.local == 'text') { - return parseSvgText(el, paintServers, bounds); + return parseSvgText(el, definitions, bounds); } else if (el.name.local == 'svg') { throw new UnsupportedError( 'Nested SVGs not supported in this implementation.'); @@ -192,7 +192,7 @@ Drawable parseSvgElement(XmlElement el, Map paintServers, } Drawable parseSvgText( - XmlElement el, Map paintServers, Rect bounds) { + XmlElement el, DrawableDefinitionServer definitions, Rect bounds) { final Offset offset = new Offset( double.parse(getAttribute(el, 'x', def: '0')), double.parse(getAttribute(el, 'y', def: '0'))); @@ -220,13 +220,13 @@ Drawable parseSvgText( /// Parses an SVG element. Drawable parseSvgGroup( - XmlElement el, Map paintServers, Rect bounds) { + XmlElement el, DrawableDefinitionServer definitions, Rect bounds) { final List children = []; final DrawableStyle style = - parseStyle(el, paintServers, bounds, needsTransform: true); + parseStyle(el, definitions, bounds, needsTransform: true); for (XmlNode child in el.children) { if (child is XmlElement) { - final Drawable el = parseSvgElement(child, paintServers, bounds, style); + final Drawable el = parseSvgElement(child, definitions, bounds, style); if (el != null) { children.add(el); } @@ -246,17 +246,17 @@ Drawable parseSvgGroup( /// /// Remember that @style attribute takes precedence. DrawableStyle parseStyle( - XmlElement el, Map paintServers, Rect bounds, + XmlElement el, DrawableDefinitionServer definitions, Rect bounds, {bool needsTransform = false, Color defaultFillIfNotSpecified}) { final Matrix4 transform = needsTransform ? parseTransform(getAttribute(el, 'transform')) : null; return new DrawableStyle( transform: transform?.storage, - stroke: parseStroke(el, bounds, paintServers), + stroke: parseStroke(el, bounds, definitions), dashArray: parseDashArray(el), dashOffset: parseDashOffset(el), - fill: parseFill(el, bounds, paintServers, defaultFillIfNotSpecified), + fill: parseFill(el, bounds, definitions, defaultFillIfNotSpecified), pathFillType: parseFillRule(el), groupOpacity: parseOpacity(el), ); diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index d69b03d90aca..2225e65db438 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -153,6 +153,57 @@ class DrawableText implements Drawable { } } +/// Contains reusable drawing elements that can be referenced by a String ID. +class DrawableDefinitionServer { + final Map _paintServers = {}; + final Map _clipPaths = {}; + + /// Attempt to lookup a pre-defined [Paint] by [id]. + /// + /// [id] and [bounds] must not be null. + Paint getPaint(String id, Rect bounds) { + assert(id != null); + assert(bounds != null); + final PaintServer srv = _paintServers[id]; + + return srv != null ? srv(bounds) : null; + } + + void addPaintServer(String id, PaintServer server) { + assert(id != null); + _paintServers[id] = server; + } + + bool applyClipPath(String id, Canvas canvas, Function drawingCallback, + {bool onlyOneDrawingOperation = false, Paint layerPaint}) { + assert(id != null); + assert(drawingCallback != null); + final Path clip = _clipPaths[id]; + if (clip == null) { + return false; + } + + canvas.save(); + canvas.clipPath(clip); + if (onlyOneDrawingOperation != true) { + layerPaint ??= new Paint(); + canvas.saveLayer(clip.getBounds(), layerPaint); + } + drawingCallback(); + if (onlyOneDrawingOperation != true) { + canvas.restore(); + } + canvas.restore(); + + return true; + } + + void addClipPath(String id, Path path) { + assert(id != null); + _clipPaths[id] = path; + } +} + /// The root element of a drawable. class DrawableRoot implements Drawable { /// The expected coordinates used by child paths for drawing. @@ -161,15 +212,17 @@ class DrawableRoot implements Drawable { /// The actual child or group to draw. final List children; - /// Contains [Paint]s that are used by multiple children, e.g. - /// gradient shaders that are referenced by an identifier. - final Map paintServers; + /// Contains reusable definitions such as gradients and clipPaths. + final DrawableDefinitionServer definitions; + // /// Contains [Paint]s that are used by multiple children, e.g. + // /// gradient shaders that are referenced by an identifier. + // final Map paintServers; /// The [DrawableStyle] for inheritence. final DrawableStyle style; const DrawableRoot( - this.viewBox, this.children, this.paintServers, this.style); + this.viewBox, this.children, this.definitions, this.style); /// Scales the `canvas` so that the drawing units in this [Drawable] /// will scale to the `desiredSize`. diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index e7cb72924459..f0df91732c6b 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -97,15 +97,16 @@ class SvgImage extends VectorDrawableImage { DrawableRoot fromSvgString(String rawSvg, Size size) { final XmlElement svg = xml.parse(rawSvg).rootElement; final Rect viewBox = parseViewBox(svg); - final Map paintServers = {}; - final DrawableStyle style = parseStyle(svg, paintServers, viewBox); + //final Map paintServers = {}; + final DrawableDefinitionServer definitions = new DrawableDefinitionServer(); + final DrawableStyle style = parseStyle(svg, definitions, viewBox); final List children = svg.children .where((XmlNode child) => child is XmlElement) .map( (XmlNode child) => parseSvgElement( child, - paintServers, + definitions, new Rect.fromPoints( Offset.zero, new Offset(size.width, size.height), @@ -117,8 +118,8 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { return new DrawableRoot( viewBox, children, - paintServers, - parseStyle(svg, paintServers, viewBox), + definitions, + parseStyle(svg, definitions, viewBox), ); } diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index e73a24504928..1487413b6233 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -388,5 +388,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.54.0.flutter-46ab040e58" + dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.55.0.flutter-43635d3372" flutter: ">=0.3.6 <2.0.0" From d7f415f0ae6b26da97c0179b3d8d1a4e5fb23076 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 19 May 2018 16:06:38 -0400 Subject: [PATCH 070/512] move path parsing out for clippath --- third_party/lib/avd.dart | 3 +- third_party/lib/src/svg/xml_parsers.dart | 95 ++++++++++++++- third_party/lib/src/svg_parser.dart | 147 ++--------------------- third_party/lib/src/vector_painter.dart | 5 +- 4 files changed, 103 insertions(+), 147 deletions(-) diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index d92b87ebd6ef..43a3ab3ddbd7 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -94,7 +94,8 @@ DrawableRoot fromAvdString(String rawSvg, Size size) { Offset.zero, new Offset(size.width, size.height)))) .toList(); // todo : style on root - return new DrawableRoot(viewBox, children, new DrawableDefinitionServer(), null); + return new DrawableRoot( + viewBox, children, new DrawableDefinitionServer(), null); } /// Creates a [DrawableRoot] from a bundled asset. diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index f07550dd9ee3..119212fae4ba 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -1,6 +1,7 @@ import 'dart:ui'; import 'package:path_drawing/path_drawing.dart'; +import 'package:vector_math/vector_math_64.dart'; import 'package:xml/xml.dart'; import '../utilities/xml.dart'; @@ -8,6 +9,19 @@ import '../vector_painter.dart'; import 'colors.dart'; import 'parsers.dart'; +typedef Path SvgPathFactory(XmlElement el); + +const Map svgPathParsers = + const { + 'circle': parsePathFromCircle, + 'path': parsePathFromPath, + 'rect': parsePathFromRect, + 'polygon': parsePathFromPolygonOrLine, + 'polyline': parsePathFromPolygonOrLine, + 'ellipse': parsePathFromEllipse, + 'line': parsePathFromLine, +}; + /// Parses an SVG @viewBox attribute (e.g. 0 0 100 100) to a [Rect]. Rect parseViewBox(XmlElement svg) { final String viewBox = getAttribute(svg, 'viewBox'); @@ -182,9 +196,7 @@ PaintServer parseRadialGradient(XmlElement el) { }; } -Path parseClipPath(XmlElement el) { - return new Path(); -} +Path parseClipPath(XmlElement el) {} /// Parses a or into a [Paint]. PaintServer parseGradient(XmlElement el) { @@ -315,3 +327,80 @@ PathFillType parseFillRule(XmlElement el) { final String rawFillRule = getAttribute(el, 'fill-rule', def: 'nonzero'); return parseRawFillRule(rawFillRule); } + +Path parsePathFromRect(XmlElement el) { + final double x = double.parse(getAttribute(el, 'x', def: '0')); + final double y = double.parse(getAttribute(el, 'y', def: '0')); + final double w = double.parse(getAttribute(el, 'width', def: '0')); + final double h = double.parse(getAttribute(el, 'height', def: '0')); + final Rect rect = new Rect.fromLTWH(x, y, w, h); + String rxRaw = getAttribute(el, 'rx', def: '0'); + String ryRaw = getAttribute(el, 'ry', def: '0'); + rxRaw ??= ryRaw; + ryRaw ??= rxRaw; + + if (rxRaw != null && rxRaw != '') { + final double rx = double.parse(rxRaw); + final double ry = double.parse(ryRaw); + + return new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)); + } + + return new Path()..addRect(rect); +} + +Path parsePathFromLine(XmlElement el) { + final double x1 = double.parse(getAttribute(el, 'x1', def: '0')); + final double x2 = double.parse(getAttribute(el, 'x2', def: '0')); + final double y1 = double.parse(getAttribute(el, 'y1', def: '0')); + final double y2 = double.parse(getAttribute(el, 'y2', def: '0')); + + return new Path() + ..moveTo(x1, y1) + ..lineTo(x2, y2); +} + +Path parsePathFromPolygonOrLine(XmlElement el) { + final String points = getAttribute(el, 'points'); + if (points == '') { + return null; + } + return parseSvgPathData('M' + points + 'z'); +} + +Path parsePathFromPath(XmlElement el) { + final String d = getAttribute(el, 'd'); + return parseSvgPathData(d); +} + +Path parsePathFromCircle(XmlElement el) { + final double cx = double.parse(getAttribute(el, 'cx', def: '0')); + final double cy = double.parse(getAttribute(el, 'cy', def: '0')); + final double r = double.parse(getAttribute(el, 'r', def: '0')); + final Rect oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); + return new Path()..addOval(oval); +} + +Path parsePathFromEllipse(XmlElement el) { + final double cx = double.parse(getAttribute(el, 'cx', def: '0')); + final double cy = double.parse(getAttribute(el, 'cy', def: '0')); + final double rx = double.parse(getAttribute(el, 'rx', def: '0')); + final double ry = double.parse(getAttribute(el, 'ry', def: '0')); + + final Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); + return new Path()..addOval(r); +} + +Path applyTransformIfNeeded(Path path, XmlElement el) { + assert(path != null); + assert(el != null); + + final Matrix4 transform = + parseTransform(getAttribute(el, 'transform', def: null)); + + if (transform != null) { + return path.transform(transform.storage); + } else { + return path; + } +} diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index b29e81f74a83..1e48b6a2bb05 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -1,7 +1,6 @@ import 'dart:ui'; import 'package:xml/xml.dart'; -import 'package:path_drawing/path_drawing.dart'; import 'package:vector_math/vector_math_64.dart'; import 'svg/colors.dart'; @@ -10,154 +9,22 @@ import 'svg/xml_parsers.dart'; import 'utilities/xml.dart'; import 'vector_painter.dart'; -typedef DrawableSvgShape SvgShapeFactory(XmlElement el, - DrawableDefinitionServer definitions, DrawableStyle parentStyle); - -final Map _shapes = { - 'circle': (XmlElement el, DrawableDefinitionServer definitions, - DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgCircle(el, definitions, parentStyle), - 'path': (XmlElement el, DrawableDefinitionServer definitions, - DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgPath(el, definitions, parentStyle), - 'rect': (XmlElement el, DrawableDefinitionServer definitions, - DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgRect(el, definitions, parentStyle), - 'polygon': (XmlElement el, DrawableDefinitionServer definitions, - DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgPolygonOrLine(el, definitions, parentStyle), - 'polyline': (XmlElement el, DrawableDefinitionServer definitions, - DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgPolygonOrLine(el, definitions, parentStyle), - 'ellipse': (XmlElement el, DrawableDefinitionServer definitions, - DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgEllipse(el, definitions, parentStyle), - 'line': (XmlElement el, DrawableDefinitionServer definitions, - DrawableStyle parentStyle) => - new DrawableSvgShape.fromSvgLine(el, definitions, parentStyle), -}; - /// An SVG Shape element that will be drawn to the canvas. class DrawableSvgShape extends DrawableShape { const DrawableSvgShape(Path path, DrawableStyle style) : super(path, style); - /// Creates a [DrawableSvgShape] from an SVG element. - factory DrawableSvgShape.fromSvgCircle(XmlElement el, - DrawableDefinitionServer definitions, DrawableStyle parentStyle) { - final double cx = double.parse(getAttribute(el, 'cx', def: '0')); - final double cy = double.parse(getAttribute(el, 'cy', def: '0')); - final double r = double.parse(getAttribute(el, 'r', def: '0')); - final Rect oval = - new Rect.fromCircle(center: new Offset(cx, cy), radius: r); - final Path path = new Path()..addOval(oval); - - return _createDrawable(path, definitions, el, parentStyle); - } - - /// Creates a [DrawableSvgShape] from an SVG element. - factory DrawableSvgShape.fromSvgPath(XmlElement el, - DrawableDefinitionServer definitions, DrawableStyle parentStyle) { - final String d = getAttribute(el, 'd'); - final Path path = parseSvgPathData(d); - - return _createDrawable(path, definitions, el, parentStyle); - } - - /// Creates a [DrawableSvgShape] from an SVG element. - factory DrawableSvgShape.fromSvgRect(XmlElement el, - DrawableDefinitionServer definitions, DrawableStyle parentStyle) { - final double x = double.parse(getAttribute(el, 'x', def: '0')); - final double y = double.parse(getAttribute(el, 'y', def: '0')); - final double w = double.parse(getAttribute(el, 'width', def: '0')); - final double h = double.parse(getAttribute(el, 'height', def: '0')); - final Rect rect = new Rect.fromLTWH(x, y, w, h); - String rxRaw = getAttribute(el, 'rx', def: '0'); - String ryRaw = getAttribute(el, 'ry', def: '0'); - rxRaw ??= ryRaw; - ryRaw ??= rxRaw; - - if (rxRaw != null && rxRaw != '') { - final double rx = double.parse(rxRaw); - final double ry = double.parse(ryRaw); - - return _createDrawable( - new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)), - definitions, - el, - parentStyle, - ); - } - - final Path path = new Path()..addRect(rect); - return _createDrawable(path, definitions, el, parentStyle); - } - - /// Creates a [DrawableSvgShape] from an SVG or element. - factory DrawableSvgShape.fromSvgPolygonOrLine(XmlElement el, - DrawableDefinitionServer definitions, DrawableStyle parentStyle) { - final String points = getAttribute(el, 'points'); - if (points == '') { - return _createDrawable(null, definitions, el, parentStyle); - } - final Path path = parseSvgPathData('M' + points + 'z'); - - return _createDrawable(path, definitions, el, parentStyle); - } - - /// Creates a [DrawableSvgShape] from an SVG element. - factory DrawableSvgShape.fromSvgEllipse(XmlElement el, - DrawableDefinitionServer definitions, DrawableStyle parentStyle) { - final double cx = double.parse(getAttribute(el, 'cx', def: '0')); - final double cy = double.parse(getAttribute(el, 'cy', def: '0')); - final double rx = double.parse(getAttribute(el, 'rx', def: '0')); - final double ry = double.parse(getAttribute(el, 'ry', def: '0')); - - final Rect r = new Rect.fromLTWH(cx - (rx / 2), cy - (ry / 2), rx, ry); - - return _createDrawable( - new Path()..addOval(r), definitions, el, parentStyle); - } - - /// Creates a [DrawableSvgShape] from an SVG element. - factory DrawableSvgShape.fromSvgLine(XmlElement el, - DrawableDefinitionServer definitions, DrawableStyle parentStyle) { - final double x1 = double.parse(getAttribute(el, 'x1', def: '0')); - final double x2 = double.parse(getAttribute(el, 'x2', def: '0')); - final double y1 = double.parse(getAttribute(el, 'y1', def: '0')); - final double y2 = double.parse(getAttribute(el, 'y2', def: '0')); - - final Path path = new Path() - ..moveTo(x1, y1) - ..lineTo(x2, y2); - return _createDrawable(path, definitions, el, parentStyle); - } - /// Applies the transformation in the @transform attribute to the path. - static Path transformPath(Path path, XmlElement el) { - assert(path != null); - assert(el != null); - - final Matrix4 transform = - parseTransform(getAttribute(el, 'transform', def: null)); - - if (transform != null) { - return path.transform(transform.storage); - } else { - return path; - } - } - - static DrawableSvgShape _createDrawable( - Path path, + factory DrawableSvgShape.parse( + SvgPathFactory pathFactory, DrawableDefinitionServer definitions, XmlElement el, DrawableStyle parentStyle) { - assert(path != null); + assert(pathFactory != null); final Color defaultFill = parentStyle?.fill != null ? null : colorBlack; - + final Path path = pathFactory(el); return new DrawableSvgShape( - transformPath(path, el), + applyTransformIfNeeded(path, el), parseStyle(el, definitions, path.getBounds(), defaultFillIfNotSpecified: defaultFill), ); @@ -169,9 +36,9 @@ class DrawableSvgShape extends DrawableShape { /// If an unsupported element is encountered, it will be created as a [DrawableNoop]. Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, Rect bounds, DrawableStyle parentStyle) { - final SvgShapeFactory shapeFn = _shapes[el.name.local]; + final SvgPathFactory shapeFn = svgPathParsers[el.name.local]; if (shapeFn != null) { - return shapeFn(el, definitions, parentStyle); + return new DrawableSvgShape.parse(shapeFn, definitions, el, parentStyle); } else if (el.name.local == 'defs') { parseDefs(el, definitions); return new DrawableNoop(el.name.local); diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 2225e65db438..3b9888b3c453 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -159,7 +159,7 @@ class DrawableDefinitionServer { final Map _clipPaths = {}; /// Attempt to lookup a pre-defined [Paint] by [id]. - /// + /// /// [id] and [bounds] must not be null. Paint getPaint(String id, Rect bounds) { assert(id != null); @@ -221,8 +221,7 @@ class DrawableRoot implements Drawable { /// The [DrawableStyle] for inheritence. final DrawableStyle style; - const DrawableRoot( - this.viewBox, this.children, this.definitions, this.style); + const DrawableRoot(this.viewBox, this.children, this.definitions, this.style); /// Scales the `canvas` so that the drawing units in this [Drawable] /// will scale to the `desiredSize`. From a7a079f632044e2e1bf6b751262ec411e8549dec Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 19 May 2018 20:54:06 -0400 Subject: [PATCH 071/512] initial clip path support; fix bug in inherit; update tiger golden --- third_party/assets/simple/clip_path.svg | 13 ++ third_party/assets/simple/clip_path_2.svg | 9 ++ third_party/example/main.dart | 2 + third_party/golden/simple/clip_path.png | Bin 0 -> 3522 bytes third_party/golden/simple/clip_path_2.png | Bin 0 -> 3177 bytes .../golden/wikimedia/Ghostscript_Tiger.png | Bin 44393 -> 44515 bytes third_party/lib/src/svg/xml_parsers.dart | 27 +++- third_party/lib/src/svg_parser.dart | 27 ++-- third_party/lib/src/vector_painter.dart | 138 ++++++++++-------- third_party/lib/svg.dart | 4 +- third_party/pubspec.yaml | 2 + third_party/test/render_svg_test.dart | 5 +- 12 files changed, 148 insertions(+), 79 deletions(-) create mode 100644 third_party/assets/simple/clip_path.svg create mode 100644 third_party/assets/simple/clip_path_2.svg create mode 100644 third_party/golden/simple/clip_path.png create mode 100644 third_party/golden/simple/clip_path_2.png diff --git a/third_party/assets/simple/clip_path.svg b/third_party/assets/simple/clip_path.svg new file mode 100644 index 000000000000..d0877e91a4ff --- /dev/null +++ b/third_party/assets/simple/clip_path.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/third_party/assets/simple/clip_path_2.svg b/third_party/assets/simple/clip_path_2.svg new file mode 100644 index 000000000000..a9707d923da3 --- /dev/null +++ b/third_party/assets/simple/clip_path_2.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 49df675bc047..6ab7c040c66c 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -6,6 +6,8 @@ const List assetNames = const [ 'assets/notfound.svg', 'assets/flutter_logo.svg', 'assets/dart.svg', + 'assets/simple/clip_path_2.svg', + 'assets/simple/clip_path.svg', 'assets/simple/group_opacity.svg', 'assets/simple/text.svg', 'assets/simple/linear_gradient.svg', diff --git a/third_party/golden/simple/clip_path.png b/third_party/golden/simple/clip_path.png new file mode 100644 index 0000000000000000000000000000000000000000..559d1b04993a68e6a66bf76ae0efe06c58a32a84 GIT binary patch literal 3522 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 APyhe` literal 0 HcmV?d00001 diff --git a/third_party/golden/simple/clip_path_2.png b/third_party/golden/simple/clip_path_2.png new file mode 100644 index 0000000000000000000000000000000000000000..975b95b77aaa383bdfb2efccdc7f0d6f293c106b GIT binary patch literal 3177 zcmbtXc{o&m7oWi(d&N((jmeg^6h*S7=VyB@V=`n-8$(72*`|gvW5_yWmo?eqhG1m-xdVPb6T)d_q|xi_j5%3v^5P6?bg{8OxVLMV1}dio{4 z9ECA{9vgeZ**SY7+WL)Zw$20inKNgCZII#oTH4wrG8pzl22VEP{=3h$Sy@^2fkU&% zq&r&W&FBR`HZ*nRpBK_s5L%gyKC`p-NkMv5!Rzx6*q>5n2lB3lBlL2cZ?6FUygV5O z50UB+78ds7Wjj&R42`bYh&D%EAdyJKye^{pzy^boAZrSz>4t52DU|sy@&)W}c`t5+ z#>*PPX&a&XE7Wp(Vpji934%rLy>L3g;@qjU>`UnMz4E6DrzIs9-#z0GScu#q?zase zh(8Mq46OH=(ij5M*qiSS>%(`}hS+yK+cMtLn7zGkD-!}T&kgn!XP797|UzupIiwh_~^?9CWF;i_U!mP$r z2S!HX8yg!3n9SmmZm{)-@o`vBPtW*=54O~Of}63BtbvuT?e8xetx^UNt>5;($VgJJ=lPl1TRkbXU)4}bqHLLzqjt(*@z&1H68Zds zv-2z4fj=~K%yg!$GGgvg($lA4Mzlh&sfKHNBm0pE{W;|IUDnrw6l}!aYD=>Kw|`bm z*Dh-C{a>8~ZC%~7-=}KsN58mH4xq80Lg`!D+&{eE7IHacO=|J&8-Vo8SlKAYpA8BS zutP(ibOF@pMW1wQ6VI(fuo^vf?xyiH24uM-$Ir*%aZ6m8x7N&0+{NOoww4yGs;Vl- z6I|~v3s-{uTFS@3g+3W(T7CVf#G>MHrbTu|oE$m#yu8dz4^+*z4M8JC&?o&^tbZIt zEp0VMm1t33TB>N!%{5TxN7rk6$aqc#05b$u1N1?m&e3WGh|9WOWXH!L3hW_*9U{t6 zVQ0P&z+b8JzpLzjwAtF-J%2;fU#Swt{5x`!o~5Fl_=xd5nKg; ze}Vy)Vl>nIQUTQ~5A2}Vdrv4H`AVv){x#>f!|rg*xd-NNYHp6h*@{5(eU+4XlPFm1 zos5&9O-Ex;0tDji=a+7)d?(20iG7TToHq(}A~^>`Xo}nmz6}&czJ*_u%Mn;xx{Q_p zkfnF5wOeXs#@9Usm$tcR0QKk}w^z%5uLS6kj?THa$C`a-0xG0ngaetF3AM^#!WARq zCsKqfwVy2YXJS3HojVUjoEovU!riFm&_lVDCG_}_YS6g3E)NnkyIQwmQOQTZ!SGw* z@Gk8^-VddzDOlwagtDlXfuqR}D`n9kB!swg8?(Je&t9h(jjCK+67M7swRLn9qsZ>R z=D4UiySrg+!K+zwkC$>S{f0ZRzSFhFc@e(`z9nd-5)uc>0Xqwi2-Gc!&< zn>))KVX%pbi7%Th`AjPZUymo=2?+^Wz$*ds7_Hfg4JElf2D+B&QHpL+tVQgih||}e z3f)nYs)<}TJdQ~cN&!Ghy`6aV9{VcFL?!tFt$Dc=^Z7f}3E=g7@9$IU`<`!w9CW_6sZ~K?o08kn zJi<34FMIG?N^ZKO2W$9Fn~U|X^y_CV+E=RS{O~Vq@|hX}%7A*jo_v=js;Vl&J3x`e zbdHyShgJYxRMm*Z4aC{h)w_i)D=;io#k^a{xnf24Pb3U+oluWS})FrFjZ(W@<@C8)QJ7xQ}urI zb_@Nh{)DOT#ECK+WU&+sCZ^jrq!;)#{!LBIr7m{LY&?ZwcmI7}6;rf&L`HrJQ2KaT zGkEsV)KF4}UgR%KgRhfz@{VQ;RbaLVwsH;U1AKHky`j$iYub?y2e+ViKDKXaX^}J>DAqd(%tt^c%(ZXUnlcWmb|-7t=x@Xb2n*9# zK6Z<otk)ud@A!|9y%PldCqtc9dA)cAYF*Hxt zDSh^LbR~sN9*wTa5IfYtn?0Wz(mi(H8RF+7*voo9i<@sTJisp d_x?lBj~5@Ix78F&fZqj>`E_g4Y7-CazX2Fn99;ka literal 0 HcmV?d00001 diff --git a/third_party/golden/wikimedia/Ghostscript_Tiger.png b/third_party/golden/wikimedia/Ghostscript_Tiger.png index 977f1ea17de3a4f7d53c40390e2c5592be3d4345..39281dbfbd122b2635621901008d11067e6b0fb5 100644 GIT binary patch literal 44515 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 N40KGi%QWo*{|^~kJ8J*{ literal 44393 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 or into a [Paint]. PaintServer parseGradient(XmlElement el) { diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 1e48b6a2bb05..1a70f4fca7ef 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -25,7 +25,7 @@ class DrawableSvgShape extends DrawableShape { final Path path = pathFactory(el); return new DrawableSvgShape( applyTransformIfNeeded(path, el), - parseStyle(el, definitions, path.getBounds(), + parseStyle(el, definitions, path.getBounds(), parentStyle, defaultFillIfNotSpecified: defaultFill), ); } @@ -47,9 +47,9 @@ Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, 'url(#${getAttribute(el, 'id')})', parseGradient(el)); return new DrawableNoop(el.name.local); } else if (el.name.local == 'g' || el.name.local == 'a') { - return parseSvgGroup(el, definitions, bounds); + return parseSvgGroup(el, definitions, bounds, parentStyle); } else if (el.name.local == 'text') { - return parseSvgText(el, definitions, bounds); + return parseSvgText(el, definitions, bounds, parentStyle); } else if (el.name.local == 'svg') { throw new UnsupportedError( 'Nested SVGs not supported in this implementation.'); @@ -58,8 +58,8 @@ Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, return new DrawableNoop(el.name.local); } -Drawable parseSvgText( - XmlElement el, DrawableDefinitionServer definitions, Rect bounds) { +Drawable parseSvgText(XmlElement el, DrawableDefinitionServer definitions, + Rect bounds, DrawableStyle parentStyle) { final Offset offset = new Offset( double.parse(getAttribute(el, 'x', def: '0')), double.parse(getAttribute(el, 'y', def: '0'))); @@ -67,7 +67,8 @@ Drawable parseSvgText( return new DrawableText( el.text, offset, - new DrawableStyle( + DrawableStyle.mergeAndBlend( + parentStyle, groupOpacity: parseOpacity(el), textStyle: new TextStyle( fontFamily: getAttribute(el, 'font-family'), @@ -86,11 +87,11 @@ Drawable parseSvgText( } /// Parses an SVG element. -Drawable parseSvgGroup( - XmlElement el, DrawableDefinitionServer definitions, Rect bounds) { +Drawable parseSvgGroup(XmlElement el, DrawableDefinitionServer definitions, + Rect bounds, DrawableStyle parentStyle) { final List children = []; final DrawableStyle style = - parseStyle(el, definitions, bounds, needsTransform: true); + parseStyle(el, definitions, bounds, parentStyle, needsTransform: true); for (XmlNode child in el.children) { if (child is XmlElement) { final Drawable el = parseSvgElement(child, definitions, bounds, style); @@ -112,13 +113,14 @@ Drawable parseSvgGroup( /// Parses style attributes or @style attribute. /// /// Remember that @style attribute takes precedence. -DrawableStyle parseStyle( - XmlElement el, DrawableDefinitionServer definitions, Rect bounds, +DrawableStyle parseStyle(XmlElement el, DrawableDefinitionServer definitions, + Rect bounds, DrawableStyle parentStyle, {bool needsTransform = false, Color defaultFillIfNotSpecified}) { final Matrix4 transform = needsTransform ? parseTransform(getAttribute(el, 'transform')) : null; - return new DrawableStyle( + return DrawableStyle.mergeAndBlend( + parentStyle, transform: transform?.storage, stroke: parseStroke(el, bounds, definitions), dashArray: parseDashArray(el), @@ -126,5 +128,6 @@ DrawableStyle parseStyle( fill: parseFill(el, bounds, definitions, defaultFillIfNotSpecified), pathFillType: parseFillRule(el), groupOpacity: parseOpacity(el), + clipPath: parseClipPath(el, definitions), ); } diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 3b9888b3c453..1bd1e08997a1 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -15,7 +15,7 @@ abstract class Drawable { /// Draws the contents or children of this [Drawable] to the `canvas`, using /// the `parentPaint` to optionally override the child's paint. - void draw(Canvas canvas, [DrawableStyle parentStyle]); + void draw(Canvas canvas); } /// Styling information for vector drawing. @@ -59,6 +59,9 @@ class DrawableStyle { /// The fill rule to use for this path. final PathFillType pathFillType; + /// The clip to apply, if any. + final Path clipPath; + /// Controls inheriting opacity. Will be averaged with child opacity. final double groupOpacity; @@ -70,28 +73,35 @@ class DrawableStyle { this.transform, this.textStyle, this.pathFillType, - this.groupOpacity}); + this.groupOpacity, + this.clipPath}); - /// Creates a new [DrawableStyle] if `other` is not null, filling in any null properties on + /// Creates a new [DrawableStyle] if `parent` is not null, filling in any null properties on /// this with the properties from other (except [groupOpacity], which is averaged). - /// - /// If `other` is null, returns this. - DrawableStyle mergeAndBlend(DrawableStyle other) { - if (other == null) { - return this; - } - + static DrawableStyle mergeAndBlend(DrawableStyle parent, + {Paint fill, + Paint stroke, + CircularIntervalList dashArray, + DashOffset dashOffset, + Float64List transform, + TextStyle textStyle, + PathFillType pathFillType, + double groupOpacity, + Path clipPath}) { final DrawableStyle ret = new DrawableStyle( - fill: identical(fill, emptyPaint) ? fill : fill ?? other.fill, - stroke: identical(stroke, emptyPaint) ? stroke : stroke ?? other.stroke, - dashArray: identical(dashArray, emptyDashArray) - ? dashArray - : dashArray ?? other.dashArray, - dashOffset: dashOffset ?? other.dashOffset, - transform: transform ?? other.transform, - textStyle: textStyle ?? other.textStyle, - pathFillType: pathFillType ?? other.pathFillType, - groupOpacity: mergeOpacity(groupOpacity, other.groupOpacity), + fill: fill ?? parent?.fill, + stroke: stroke ?? parent?.stroke, + dashArray: dashArray ?? parent?.dashArray, + dashOffset: dashOffset ?? parent?.dashOffset, + // transforms aren't inherited because they're applied to canvas with save/restore + // that wraps any potential children + transform: transform, + textStyle: textStyle ?? parent?.textStyle, + pathFillType: pathFillType ?? parent?.pathFillType, + groupOpacity: mergeOpacity(groupOpacity, parent?.groupOpacity), + // clips don't make sense to inherit - applied to canvas with save/restore + // that wraps any potential children + clipPath: clipPath, ); if (ret.fill != null) { @@ -119,7 +129,6 @@ class DrawableStyle { return back; } return (front + back) / 2.0; - //return back + (1.0 - back) * front; } } @@ -145,7 +154,7 @@ class DrawableText implements Drawable { bool get isVisible => _paragraph.width > 0.0; @override - void draw(Canvas canvas, [DrawableStyle parentStyle]) { + void draw(Canvas canvas) { if (!isVisible) { return; } @@ -174,28 +183,9 @@ class DrawableDefinitionServer { _paintServers[id] = server; } - bool applyClipPath(String id, Canvas canvas, Function drawingCallback, - {bool onlyOneDrawingOperation = false, Paint layerPaint}) { + Path getClipPath(String id) { assert(id != null); - assert(drawingCallback != null); - final Path clip = _clipPaths[id]; - if (clip == null) { - return false; - } - - canvas.save(); - canvas.clipPath(clip); - if (onlyOneDrawingOperation != true) { - layerPaint ??= new Paint(); - canvas.saveLayer(clip.getBounds(), layerPaint); - } - drawingCallback(); - if (onlyOneDrawingOperation != true) { - canvas.restore(); - } - canvas.restore(); - - return true; + return _clipPaths[id]; } void addClipPath(String id, Path path) { @@ -256,12 +246,12 @@ class DrawableRoot implements Drawable { children.isNotEmpty == true && viewBox != null && !viewBox.isEmpty; @override - void draw(Canvas canvas, [DrawableStyle parentStyle]) { + void draw(Canvas canvas) { if (!isVisible) { return; } for (Drawable child in children) { - child.draw(canvas, style?.mergeAndBlend(parentStyle) ?? parentStyle); + child.draw(canvas); } } } @@ -277,7 +267,7 @@ class DrawableNoop implements Drawable { bool get isVisible => false; @override - void draw(Canvas canvas, [DrawableStyle parentStyle]) {} + void draw(Canvas canvas) {} } /// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. @@ -291,20 +281,36 @@ class DrawableGroup implements Drawable { bool get isVisible => children != null && children.isNotEmpty; @override - void draw(Canvas canvas, [DrawableStyle parentStyle]) { + void draw(Canvas canvas) { if (!isVisible) { return; } + + if (style?.clipPath != null) { + canvas.save(); + canvas.clipPath(style.clipPath); + if (children.length > 1) { + canvas.saveLayer(style.clipPath.getBounds(), DrawableStyle.emptyPaint); + } + } + if (style?.transform != null) { canvas.save(); canvas.transform(style?.transform); } for (Drawable child in children) { - child.draw(canvas, style?.mergeAndBlend(parentStyle) ?? parentStyle); + child.draw(canvas); } if (style?.transform != null) { canvas.restore(); } + + if (style?.clipPath != null) { + if (children.length > 1) { + canvas.restore(); + } + canvas.restore(); + } } } @@ -325,31 +331,39 @@ class DrawableShape implements Drawable { bool get isVisible => bounds.width + bounds.height > 0; @override - void draw(Canvas canvas, [DrawableStyle parentStyle]) { + void draw(Canvas canvas) { if (!isVisible) { return; } - final DrawableStyle localStyle = style.mergeAndBlend(parentStyle); - path.fillType = localStyle.pathFillType ?? PathFillType.nonZero; - if (localStyle?.fill != null && - !identical(localStyle.fill, DrawableStyle.emptyPaint)) { - canvas.drawPath(path, localStyle.fill); + path.fillType = style.pathFillType ?? PathFillType.nonZero; + + if (style?.clipPath != null) { + canvas.save(); + canvas.clipPath(style.clipPath); + } + + if (style?.fill != null && + !identical(style.fill, DrawableStyle.emptyPaint)) { + canvas.drawPath(path, style.fill); } - if (localStyle?.stroke != null && - !identical(localStyle.stroke, DrawableStyle.emptyPaint)) { - if (localStyle.dashArray != null && - !identical(localStyle.dashArray, DrawableStyle.emptyDashArray)) { + if (style?.stroke != null && + !identical(style.stroke, DrawableStyle.emptyPaint)) { + if (style.dashArray != null && + !identical(style.dashArray, DrawableStyle.emptyDashArray)) { canvas.drawPath( dashPath(path, - dashArray: localStyle.dashArray, - dashOffset: localStyle.dashOffset), - localStyle.stroke); + dashArray: style.dashArray, dashOffset: style.dashOffset), + style.stroke); } else { - canvas.drawPath(path, localStyle.stroke); + canvas.drawPath(path, style.stroke); } } + + if (style?.clipPath != null) { + canvas.restore(); + } } } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index f0df91732c6b..afc8e9fd8f68 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -99,7 +99,7 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { final Rect viewBox = parseViewBox(svg); //final Map paintServers = {}; final DrawableDefinitionServer definitions = new DrawableDefinitionServer(); - final DrawableStyle style = parseStyle(svg, definitions, viewBox); + final DrawableStyle style = parseStyle(svg, definitions, viewBox, null); final List children = svg.children .where((XmlNode child) => child is XmlElement) @@ -119,7 +119,7 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { viewBox, children, definitions, - parseStyle(svg, definitions, viewBox), + parseStyle(svg, definitions, viewBox, null), ); } diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index b213c7d1333f..34c0b1bb752c 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -47,6 +47,8 @@ flutter: - assets/deborah_ufw/new-play-button.svg - assets/deborah_ufw/new-send-circle.svg - assets/deborah_ufw/numeric_25.svg + - assets/simple/clip_path_2.svg + - assets/simple/clip_path.svg - assets/simple/ellipse.svg - assets/simple/group_opacity.svg - assets/simple/nested_group.svg diff --git a/third_party/test/render_svg_test.dart b/third_party/test/render_svg_test.dart index c6381f090c1d..4328fd4ba44c 100644 --- a/third_party/test/render_svg_test.dart +++ b/third_party/test/render_svg_test.dart @@ -32,7 +32,10 @@ void main() { await golden.getSvgPngBytes(await svgAssetFile.readAsString()); final Uint8List goldenBytes = await goldenFile.readAsBytes(); - + if (goldenFile.path.contains('Ghost')) { + final File tmp = new File('/Users/dnfield/tmp/gstiger2.png'); + tmp.writeAsBytesSync(bytes); + } expect(bytes, orderedEquals(goldenBytes), reason: '${goldenFile.path} does not match rendered output of ${svgAssetFile.path}!'); From 5d9801ab38a8b75135e2292bc1b98820da40ec23 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 19 May 2018 20:57:49 -0400 Subject: [PATCH 072/512] remove temporary testing code --- third_party/test/render_svg_test.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/third_party/test/render_svg_test.dart b/third_party/test/render_svg_test.dart index 4328fd4ba44c..c6381f090c1d 100644 --- a/third_party/test/render_svg_test.dart +++ b/third_party/test/render_svg_test.dart @@ -32,10 +32,7 @@ void main() { await golden.getSvgPngBytes(await svgAssetFile.readAsString()); final Uint8List goldenBytes = await goldenFile.readAsBytes(); - if (goldenFile.path.contains('Ghost')) { - final File tmp = new File('/Users/dnfield/tmp/gstiger2.png'); - tmp.writeAsBytesSync(bytes); - } + expect(bytes, orderedEquals(goldenBytes), reason: '${goldenFile.path} does not match rendered output of ${svgAssetFile.path}!'); From c2ac7bd4846447bce895c68bea9f4b4ece08e2dd Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 20 May 2018 07:23:14 -0400 Subject: [PATCH 073/512] support multiple clips --- third_party/CHANGELOG.md | 7 ++ third_party/assets/simple/clip_path_3.svg | 13 +++ third_party/example/main.dart | 61 +++++++------ third_party/lib/src/svg/xml_parsers.dart | 24 +++-- third_party/lib/src/vector_painter.dart | 106 ++++++++++++---------- third_party/pubspec.yaml | 3 +- 6 files changed, 130 insertions(+), 84 deletions(-) create mode 100644 third_party/assets/simple/clip_path_3.svg diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index a1df18dc6252..b910e4ab4030 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGES +## 0.2.0 + +- Fix bug(s) in inheritence (better rendering of Ghostscript_Tiger.svg) +- Support for ``s +- Refactoring of how gradients are handled to enable clipPaths +- Refactor of SVG shape -> path logic + ## 0.1.4 - Fix bugs in `` percentage handling. diff --git a/third_party/assets/simple/clip_path_3.svg b/third_party/assets/simple/clip_path_3.svg new file mode 100644 index 000000000000..aae181a1e7dc --- /dev/null +++ b/third_party/assets/simple/clip_path_3.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 6ab7c040c66c..5a3cca195566 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -3,41 +3,42 @@ import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; const List assetNames = const [ - 'assets/notfound.svg', - 'assets/flutter_logo.svg', - 'assets/dart.svg', + //'assets/notfound.svg', + // 'assets/flutter_logo.svg', + // 'assets/dart.svg', + 'assets/simple/clip_path_3.svg', 'assets/simple/clip_path_2.svg', 'assets/simple/clip_path.svg', - 'assets/simple/group_opacity.svg', - 'assets/simple/text.svg', - 'assets/simple/linear_gradient.svg', - 'assets/simple/linear_gradient_2.svg', - 'assets/simple/radial_gradient.svg', - 'assets/simple/rect_rrect.svg', - 'assets/simple/style_attr.svg', - 'assets/w3samples/aa.svg', - 'assets/w3samples/alphachannel.svg', - 'assets/deborah_ufw/new-action-expander.svg', - 'assets/deborah_ufw/new-camera.svg', - 'assets/deborah_ufw/new-gif-button.svg', - 'assets/deborah_ufw/new-gif.svg', - 'assets/deborah_ufw/new-image.svg', - 'assets/deborah_ufw/new-mention.svg', - 'assets/deborah_ufw/new-pause-button.svg', - 'assets/deborah_ufw/new-play-button.svg', - 'assets/deborah_ufw/new-send-circle.svg', - 'assets/deborah_ufw/numeric_25.svg', - 'assets/simple/ellipse.svg', - 'assets/simple/dash_path.svg', - 'assets/simple/nested_group.svg', - 'assets/wikimedia/chess_knight.svg', - 'assets/wikimedia/Ghostscript_Tiger.svg', + // 'assets/simple/group_opacity.svg', + // 'assets/simple/text.svg', + // 'assets/simple/linear_gradient.svg', + // 'assets/simple/linear_gradient_2.svg', + // 'assets/simple/radial_gradient.svg', + // 'assets/simple/rect_rrect.svg', + // 'assets/simple/style_attr.svg', + // 'assets/w3samples/aa.svg', + // 'assets/w3samples/alphachannel.svg', + // 'assets/deborah_ufw/new-action-expander.svg', + // 'assets/deborah_ufw/new-camera.svg', + // 'assets/deborah_ufw/new-gif-button.svg', + // 'assets/deborah_ufw/new-gif.svg', + // 'assets/deborah_ufw/new-image.svg', + // 'assets/deborah_ufw/new-mention.svg', + // 'assets/deborah_ufw/new-pause-button.svg', + // 'assets/deborah_ufw/new-play-button.svg', + // 'assets/deborah_ufw/new-send-circle.svg', + // 'assets/deborah_ufw/numeric_25.svg', + // 'assets/simple/ellipse.svg', + // 'assets/simple/dash_path.svg', + // 'assets/simple/nested_group.svg', + // 'assets/wikimedia/chess_knight.svg', + // 'assets/wikimedia/Ghostscript_Tiger.svg', ]; const List uriNames = const [ - 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', - 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', + // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', + // 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', ]; void main() => runApp(new MyApp()); diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 10d82cd30009..c25231a8a94f 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -196,13 +196,24 @@ PaintServer parseRadialGradient(XmlElement el) { }; } -Path parseClipPathDefinition(XmlElement el) { - final Path ret = new Path(); +List parseClipPathDefinition(XmlElement el) { + final List ret = []; + Path currentPath; for (XmlNode child in el.children) { if (child is XmlElement) { final SvgPathFactory pathFn = svgPathParsers[child.name.local]; if (pathFn != null) { - ret.addPath(applyTransformIfNeeded(pathFn(child), el), Offset.zero); + final Path nextPath = applyTransformIfNeeded(pathFn(child), child); + nextPath.fillType = parseFillRule(child, 'clip-rule'); + if (currentPath != null && nextPath.fillType != currentPath.fillType) { + currentPath = nextPath; + ret.add(currentPath); + } else if (currentPath == null) { + currentPath = nextPath; + ret.add(currentPath); + } else { + currentPath.addPath(nextPath, Offset.zero); + } } else { print('Unsupported clipPath child ${el.name.local}'); } @@ -212,7 +223,7 @@ Path parseClipPathDefinition(XmlElement el) { return ret; } -Path parseClipPath(XmlElement el, DrawableDefinitionServer definitions) { +List parseClipPath(XmlElement el, DrawableDefinitionServer definitions) { final String rawClipAttribute = getAttribute(el, 'clip-path'); if (rawClipAttribute != '') { return definitions.getClipPath(rawClipAttribute); @@ -346,8 +357,9 @@ Paint parseFill(XmlElement el, Rect bounds, ..style = PaintingStyle.fill; } -PathFillType parseFillRule(XmlElement el) { - final String rawFillRule = getAttribute(el, 'fill-rule', def: 'nonzero'); +PathFillType parseFillRule(XmlElement el, + [String attr = 'fill-rule', String def = 'nonzero']) { + final String rawFillRule = getAttribute(el, attr, def: def); return parseRawFillRule(rawFillRule); } diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 1bd1e08997a1..7481aa79766d 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -60,7 +60,7 @@ class DrawableStyle { final PathFillType pathFillType; /// The clip to apply, if any. - final Path clipPath; + final List clipPath; /// Controls inheriting opacity. Will be averaged with child opacity. final double groupOpacity; @@ -87,7 +87,7 @@ class DrawableStyle { TextStyle textStyle, PathFillType pathFillType, double groupOpacity, - Path clipPath}) { + List clipPath}) { final DrawableStyle ret = new DrawableStyle( fill: fill ?? parent?.fill, stroke: stroke ?? parent?.stroke, @@ -165,7 +165,7 @@ class DrawableText implements Drawable { /// Contains reusable drawing elements that can be referenced by a String ID. class DrawableDefinitionServer { final Map _paintServers = {}; - final Map _clipPaths = {}; + final Map> _clipPaths = >{}; /// Attempt to lookup a pre-defined [Paint] by [id]. /// @@ -183,14 +183,14 @@ class DrawableDefinitionServer { _paintServers[id] = server; } - Path getClipPath(String id) { + List getClipPath(String id) { assert(id != null); return _clipPaths[id]; } - void addClipPath(String id, Path path) { + void addClipPath(String id, List paths) { assert(id != null); - _clipPaths[id] = path; + _clipPaths[id] = paths; } } @@ -286,30 +286,37 @@ class DrawableGroup implements Drawable { return; } - if (style?.clipPath != null) { - canvas.save(); - canvas.clipPath(style.clipPath); - if (children.length > 1) { - canvas.saveLayer(style.clipPath.getBounds(), DrawableStyle.emptyPaint); + final Function innerDraw = () { + if (style?.transform != null) { + canvas.save(); + canvas.transform(style?.transform); } - } + for (Drawable child in children) { + child.draw(canvas); + } + if (style?.transform != null) { + canvas.restore(); + } + }; - if (style?.transform != null) { - canvas.save(); - canvas.transform(style?.transform); - } - for (Drawable child in children) { - child.draw(canvas); - } - if (style?.transform != null) { - canvas.restore(); - } + if (style?.clipPath?.isNotEmpty == true) { + for (Path clipPath in style.clipPath) { + canvas.save(); + canvas.clipPath(clipPath); + + if (children.length > 1) { + canvas.saveLayer(clipPath.getBounds(), DrawableStyle.emptyPaint); + } - if (style?.clipPath != null) { - if (children.length > 1) { + innerDraw(); + + if (children.length > 1) { + canvas.restore(); + } canvas.restore(); } - canvas.restore(); + } else { + innerDraw(); } } } @@ -338,31 +345,36 @@ class DrawableShape implements Drawable { path.fillType = style.pathFillType ?? PathFillType.nonZero; - if (style?.clipPath != null) { - canvas.save(); - canvas.clipPath(style.clipPath); - } - - if (style?.fill != null && - !identical(style.fill, DrawableStyle.emptyPaint)) { - canvas.drawPath(path, style.fill); - } + // if we have multiple clips to apply, need to wrap this in a loop. + final Function innerDraw = () { + if (style?.fill != null && + !identical(style.fill, DrawableStyle.emptyPaint)) { + canvas.drawPath(path, style.fill); + } - if (style?.stroke != null && - !identical(style.stroke, DrawableStyle.emptyPaint)) { - if (style.dashArray != null && - !identical(style.dashArray, DrawableStyle.emptyDashArray)) { - canvas.drawPath( - dashPath(path, - dashArray: style.dashArray, dashOffset: style.dashOffset), - style.stroke); - } else { - canvas.drawPath(path, style.stroke); + if (style?.stroke != null && + !identical(style.stroke, DrawableStyle.emptyPaint)) { + if (style.dashArray != null && + !identical(style.dashArray, DrawableStyle.emptyDashArray)) { + canvas.drawPath( + dashPath(path, + dashArray: style.dashArray, dashOffset: style.dashOffset), + style.stroke); + } else { + canvas.drawPath(path, style.stroke); + } } - } + }; - if (style?.clipPath != null) { - canvas.restore(); + if (style?.clipPath?.isNotEmpty == true) { + for (Path clip in style.clipPath) { + canvas.save(); + canvas.clipPath(clip); + innerDraw(); + canvas.restore(); + } + } else { + innerDraw(); } } } diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 34c0b1bb752c..65cbd186897f 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.1.4 +version: 0.2.0 dependencies: path_drawing: ^0.2.3 @@ -47,6 +47,7 @@ flutter: - assets/deborah_ufw/new-play-button.svg - assets/deborah_ufw/new-send-circle.svg - assets/deborah_ufw/numeric_25.svg + - assets/simple/clip_path_3.svg - assets/simple/clip_path_2.svg - assets/simple/clip_path.svg - assets/simple/ellipse.svg From e30ac227085232ab76bc852411f64797505a749d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 20 May 2018 07:26:01 -0400 Subject: [PATCH 074/512] uncomment code --- third_party/example/main.dart | 60 +++++++++++++++++------------------ 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 5a3cca195566..4ad11c79fd45 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -3,42 +3,42 @@ import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; const List assetNames = const [ - //'assets/notfound.svg', - // 'assets/flutter_logo.svg', - // 'assets/dart.svg', + 'assets/notfound.svg', + 'assets/flutter_logo.svg', + 'assets/dart.svg', 'assets/simple/clip_path_3.svg', 'assets/simple/clip_path_2.svg', 'assets/simple/clip_path.svg', - // 'assets/simple/group_opacity.svg', - // 'assets/simple/text.svg', - // 'assets/simple/linear_gradient.svg', - // 'assets/simple/linear_gradient_2.svg', - // 'assets/simple/radial_gradient.svg', - // 'assets/simple/rect_rrect.svg', - // 'assets/simple/style_attr.svg', - // 'assets/w3samples/aa.svg', - // 'assets/w3samples/alphachannel.svg', - // 'assets/deborah_ufw/new-action-expander.svg', - // 'assets/deborah_ufw/new-camera.svg', - // 'assets/deborah_ufw/new-gif-button.svg', - // 'assets/deborah_ufw/new-gif.svg', - // 'assets/deborah_ufw/new-image.svg', - // 'assets/deborah_ufw/new-mention.svg', - // 'assets/deborah_ufw/new-pause-button.svg', - // 'assets/deborah_ufw/new-play-button.svg', - // 'assets/deborah_ufw/new-send-circle.svg', - // 'assets/deborah_ufw/numeric_25.svg', - // 'assets/simple/ellipse.svg', - // 'assets/simple/dash_path.svg', - // 'assets/simple/nested_group.svg', - // 'assets/wikimedia/chess_knight.svg', - // 'assets/wikimedia/Ghostscript_Tiger.svg', + 'assets/simple/group_opacity.svg', + 'assets/simple/text.svg', + 'assets/simple/linear_gradient.svg', + 'assets/simple/linear_gradient_2.svg', + 'assets/simple/radial_gradient.svg', + 'assets/simple/rect_rrect.svg', + 'assets/simple/style_attr.svg', + 'assets/w3samples/aa.svg', + 'assets/w3samples/alphachannel.svg', + 'assets/deborah_ufw/new-action-expander.svg', + 'assets/deborah_ufw/new-camera.svg', + 'assets/deborah_ufw/new-gif-button.svg', + 'assets/deborah_ufw/new-gif.svg', + 'assets/deborah_ufw/new-image.svg', + 'assets/deborah_ufw/new-mention.svg', + 'assets/deborah_ufw/new-pause-button.svg', + 'assets/deborah_ufw/new-play-button.svg', + 'assets/deborah_ufw/new-send-circle.svg', + 'assets/deborah_ufw/numeric_25.svg', + 'assets/simple/ellipse.svg', + 'assets/simple/dash_path.svg', + 'assets/simple/nested_group.svg', + 'assets/wikimedia/chess_knight.svg', + 'assets/wikimedia/Ghostscript_Tiger.svg', ]; const List uriNames = const [ - // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', - // 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', + 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', + 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', ]; void main() => runApp(new MyApp()); From f41a4400d96f82980b184cf451c668bbb1ca55e0 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 20 May 2018 07:27:34 -0400 Subject: [PATCH 075/512] add golden file --- third_party/golden/simple/clip_path_3.png | Bin 0 -> 2974 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 third_party/golden/simple/clip_path_3.png diff --git a/third_party/golden/simple/clip_path_3.png b/third_party/golden/simple/clip_path_3.png new file mode 100644 index 0000000000000000000000000000000000000000..76fed26010ebcc53e58ac640faba36070223a17d GIT binary patch literal 2974 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 literal 0 HcmV?d00001 From 928306f050be46dfe999c2f8a64f2d210624bb2f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 20 May 2018 15:02:05 -0400 Subject: [PATCH 076/512] support color replacement, rename enum values to match dart style --- third_party/example/main.dart | 30 +++++++++++--- third_party/lib/avd.dart | 6 +-- third_party/lib/src/svg/xml_parsers.dart | 40 ++++++++++++------- third_party/lib/src/svg_parser.dart | 8 ++-- third_party/lib/src/vector_painter.dart | 17 +++++++- third_party/lib/svg.dart | 51 ++++++++++++++++-------- third_party/lib/vector_drawable.dart | 11 +++-- 7 files changed, 114 insertions(+), 49 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 4ad11c79fd45..09c6eb3942a3 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -18,6 +18,14 @@ const List assetNames = const [ 'assets/simple/style_attr.svg', 'assets/w3samples/aa.svg', 'assets/w3samples/alphachannel.svg', + 'assets/simple/ellipse.svg', + 'assets/simple/dash_path.svg', + 'assets/simple/nested_group.svg', + 'assets/wikimedia/chess_knight.svg', + 'assets/wikimedia/Ghostscript_Tiger.svg', +]; + +const List iconAssetNames = const [ 'assets/deborah_ufw/new-action-expander.svg', 'assets/deborah_ufw/new-camera.svg', 'assets/deborah_ufw/new-gif-button.svg', @@ -28,11 +36,6 @@ const List assetNames = const [ 'assets/deborah_ufw/new-play-button.svg', 'assets/deborah_ufw/new-send-circle.svg', 'assets/deborah_ufw/numeric_25.svg', - 'assets/simple/ellipse.svg', - 'assets/simple/dash_path.svg', - 'assets/simple/nested_group.svg', - 'assets/wikimedia/chess_knight.svg', - 'assets/wikimedia/Ghostscript_Tiger.svg', ]; const List uriNames = const [ @@ -51,6 +54,7 @@ class MyApp extends StatelessWidget { title: 'Flutter Demo', theme: new ThemeData( primarySwatch: Colors.blue, + iconTheme: const IconThemeData(color: Colors.blueGrey) ), home: const MyHomePage(title: 'Flutter SVG Demo'), ); @@ -95,6 +99,22 @@ class _MyHomePageState extends State { ); } + for (String assetName in iconAssetNames) { + _painters.add( + new SvgImage.asset( + assetName, + new Size(_dimension, _dimension), + errorWidgetBuilder: customErrorBuilder, + colorReplacer: (Color color) { + print(color); + if (color.value == 0xFF000000) { + return Theme.of(context).iconTheme.color; + } + }, + ), + ); + } + for (String uriName in uriNames) { _painters.add( new SvgImage.network( diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 43a3ab3ddbd7..009a6108dfed 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -30,7 +30,7 @@ class AvdImage extends VectorDrawableImage { factory AvdImage.fromString(String svg, Size size, {Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( @@ -49,7 +49,7 @@ class AvdImage extends VectorDrawableImage { AssetBundle bundle, String package, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( @@ -67,7 +67,7 @@ class AvdImage extends VectorDrawableImage { {Map headers, Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index c25231a8a94f..89f0b299cda1 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -59,7 +59,8 @@ void parseDefs(XmlElement el, DrawableDefinitionServer definitions) { for (XmlNode def in el.children) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { - definitions.addPaintServer(buildUrlIri(def), parseGradient(def)); + definitions.addPaintServer( + buildUrlIri(def), parseGradient(def, definitions)); } else if (def.name.local == 'clipPath') { definitions.addClipPath(buildUrlIri(def), parseClipPathDefinition(def)); } @@ -90,11 +91,17 @@ TileMode parseTileMode(XmlElement el) { } void parseStops( - List stops, List colors, List offsets) { + List stops, + List colors, + List offsets, + DrawableDefinitionServer definitions, +) { for (int i = 0; i < stops.length; i++) { final String rawOpacity = getAttribute(stops[i], 'stop-opacity', def: '1'); - colors[i] = parseColor(getAttribute(stops[i], 'stop-color')) - .withOpacity(double.parse(rawOpacity)); + colors[i] = definitions.replaceColor( + parseColor(getAttribute(stops[i], 'stop-color')) + .withOpacity(double.parse(rawOpacity)), + ); final String rawOffset = getAttribute(stops[i], 'offset'); offsets[i] = _parseDecimalOrPercentage(rawOffset); @@ -102,7 +109,8 @@ void parseStops( } /// Parses an SVG element into a [Paint]. -PaintServer parseLinearGradient(XmlElement el) { +PaintServer parseLinearGradient( + XmlElement el, DrawableDefinitionServer definitions) { final double x1 = _parseDecimalOrPercentage(getAttribute(el, 'x1', def: '0%')); final double x2 = @@ -117,7 +125,7 @@ PaintServer parseLinearGradient(XmlElement el) { final List colors = new List(stops.length); final List offsets = new List(stops.length); - parseStops(stops, colors, offsets); + parseStops(stops, colors, offsets, definitions); return (Rect bounds) { final Offset from = new Offset( @@ -142,7 +150,8 @@ PaintServer parseLinearGradient(XmlElement el) { } /// Parses a into a [Paint]. -PaintServer parseRadialGradient(XmlElement el) { +PaintServer parseRadialGradient( + XmlElement el, DrawableDefinitionServer definitions) { final String rawCx = getAttribute(el, 'cx', def: '50%'); final String rawCy = getAttribute(el, 'cy', def: '50%'); final TileMode spreadMethod = parseTileMode(el); @@ -151,7 +160,7 @@ PaintServer parseRadialGradient(XmlElement el) { final List colors = new List(stops.length); final List offsets = new List(stops.length); - parseStops(stops, colors, offsets); + parseStops(stops, colors, offsets, definitions); return (Rect bounds) { final double cx = _parseDecimalOrPercentage( @@ -233,11 +242,11 @@ List parseClipPath(XmlElement el, DrawableDefinitionServer definitions) { } /// Parses a or into a [Paint]. -PaintServer parseGradient(XmlElement el) { +PaintServer parseGradient(XmlElement el, DrawableDefinitionServer definitions) { if (el.name.local == 'linearGradient') { - return parseLinearGradient(el); + return parseLinearGradient(el, definitions); } else if (el.name.local == 'radialGradient') { - return parseRadialGradient(el); + return parseRadialGradient(el, definitions); } throw new StateError('Unknown gradient type ${el.name.local}'); } @@ -302,7 +311,8 @@ Paint parseStroke( final double opacity = rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); final Paint paint = new Paint() - ..color = parseColor(rawStroke).withOpacity(opacity) + ..color = + definitions.replaceColor(parseColor(rawStroke).withOpacity(opacity)) ..style = PaintingStyle.stroke; final String rawStrokeCap = getAttribute(el, 'stroke-linecap'); @@ -336,7 +346,8 @@ Paint parseFill(XmlElement el, Rect bounds, if (defaultFillIfNotSpecified == null) { return null; } - return new Paint()..color = defaultFillIfNotSpecified; + return new Paint() + ..color = definitions.replaceColor(defaultFillIfNotSpecified); } else if (rawFill == 'none') { return DrawableStyle.emptyPaint; } @@ -350,7 +361,8 @@ Paint parseFill(XmlElement el, Rect bounds, ? rawFill == 'none' ? 0.0 : 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); - final Color fill = parseColor(rawFill).withOpacity(opacity); + final Color fill = + definitions.replaceColor(parseColor(rawFill).withOpacity(opacity)); return new Paint() ..color = fill diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 1a70f4fca7ef..ab3763bab9e7 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -44,7 +44,7 @@ Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, return new DrawableNoop(el.name.local); } else if (el.name.local.endsWith('Gradient')) { definitions.addPaintServer( - 'url(#${getAttribute(el, 'id')})', parseGradient(el)); + 'url(#${getAttribute(el, 'id')})', parseGradient(el, definitions)); return new DrawableNoop(el.name.local); } else if (el.name.local == 'g' || el.name.local == 'a') { return parseSvgGroup(el, definitions, bounds, parentStyle); @@ -73,12 +73,12 @@ Drawable parseSvgText(XmlElement el, DrawableDefinitionServer definitions, textStyle: new TextStyle( fontFamily: getAttribute(el, 'font-family'), fontSize: double.parse(getAttribute(el, 'font-size', def: '55')), - color: parseColor( - getAttribute( + color: definitions.replaceColor( + parseColor(getAttribute( el, 'fill', def: getAttribute(el, 'stroke', def: 'black'), - ), + )), ), height: -1.0, ), diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 7481aa79766d..7255e504f130 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -1,12 +1,16 @@ import 'dart:typed_data'; import 'dart:ui'; -import 'package:path_drawing/path_drawing.dart'; import 'package:flutter/widgets.dart' hide TextStyle; import 'package:meta/meta.dart'; +import 'package:path_drawing/path_drawing.dart'; +/// Callback used to calculate gradients. typedef Paint PaintServer(Rect bounds); +/// Callback signature for color replacements. +typedef Color ColorReplacer(Color parsedColor); + /// Base interface for vector drawing. @immutable abstract class Drawable { @@ -164,9 +168,20 @@ class DrawableText implements Drawable { /// Contains reusable drawing elements that can be referenced by a String ID. class DrawableDefinitionServer { + DrawableDefinitionServer({ColorReplacer colorReplacer}) + : _colorReplacer = colorReplacer; + + final ColorReplacer _colorReplacer; final Map _paintServers = {}; final Map> _clipPaths = >{}; + Color replaceColor(Color original) { + if (_colorReplacer == null) { + return original; + } + return _colorReplacer(original) ?? original; + } + /// Attempt to lookup a pre-defined [Paint] by [id]. /// /// [id] and [bounds] must not be null. diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index afc8e9fd8f68..1a3956fa5d8f 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -32,12 +32,14 @@ class SvgImage extends VectorDrawableImage { factory SvgImage.fromString(String svg, Size size, {Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, Widget child, ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) { + WidgetBuilder loadingPlaceholderBuilder, + ColorReplacer colorReplacer}) { return new SvgImage._( - new Future.value(fromSvgString(svg, size)), + new Future.value( + fromSvgString(svg, size, colorReplacer: colorReplacer)), size, clipToViewBox: clipToViewBox, child: child, @@ -54,12 +56,14 @@ class SvgImage extends VectorDrawableImage { AssetBundle bundle, String package, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, Widget child, ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) { + WidgetBuilder loadingPlaceholderBuilder, + ColorReplacer colorReplacer}) { return new SvgImage._( - loadAsset(assetName, size, bundle: bundle, package: package), + loadAsset(assetName, size, + bundle: bundle, package: package, colorReplacer: colorReplacer), size, clipToViewBox: clipToViewBox, child: child, @@ -76,11 +80,12 @@ class SvgImage extends VectorDrawableImage { Key key, bool clipToViewBox = true, Widget child, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) { + WidgetBuilder loadingPlaceholderBuilder, + ColorReplacer colorReplacer}) { return new SvgImage._( - loadNetworkAsset(uri, size), + loadNetworkAsset(uri, size, colorReplacer: colorReplacer), size, clipToViewBox: clipToViewBox, child: child, @@ -94,11 +99,16 @@ class SvgImage extends VectorDrawableImage { /// Creates a [DrawableRoot] from a string of SVG data. [size] specifies the /// size of the coordinate space to draw to. -DrawableRoot fromSvgString(String rawSvg, Size size) { +DrawableRoot fromSvgString( + String rawSvg, + Size size, { + ColorReplacer colorReplacer, +}) { final XmlElement svg = xml.parse(rawSvg).rootElement; final Rect viewBox = parseViewBox(svg); //final Map paintServers = {}; - final DrawableDefinitionServer definitions = new DrawableDefinitionServer(); + final DrawableDefinitionServer definitions = + new DrawableDefinitionServer(colorReplacer: colorReplacer); final DrawableStyle style = parseStyle(svg, definitions, viewBox, null); final List children = svg.children @@ -125,20 +135,29 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { /// Creates a [DrawableRoot] from a bundled asset. [size] specifies the size /// of the coordinate space to draw to. -Future loadAsset(String assetName, Size size, - {AssetBundle bundle, String package}) async { +Future loadAsset( + String assetName, + Size size, { + ColorReplacer colorReplacer, + AssetBundle bundle, + String package, +}) async { bundle ??= rootBundle; final String rawSvg = await bundle.loadString( package == null ? assetName : 'packages/$package/$assetName', ); - return fromSvgString(rawSvg, size); + return fromSvgString(rawSvg, size, colorReplacer: colorReplacer); } final HttpClient _httpClient = new HttpClient(); /// Creates a [DrawableRoot] from a network asset with an HTTP get request. /// [size] specifies the size of the coordinate space to draw to. -Future loadNetworkAsset(String url, Size size) async { +Future loadNetworkAsset( + String url, + Size size, { + ColorReplacer colorReplacer, +}) async { final Uri uri = Uri.base.resolve(url); final HttpClientRequest request = await _httpClient.getUrl(uri); final HttpClientResponse response = await request.close(); @@ -148,7 +167,7 @@ Future loadNetworkAsset(String url, Size size) async { } final String rawSvg = await _consolidateHttpClientResponse(response); - return fromSvgString(rawSvg, size); + return fromSvgString(rawSvg, size, colorReplacer: colorReplacer); } Future _consolidateHttpClientResponse( diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart index a9dbdd642e11..fa89310b038c 100644 --- a/third_party/lib/vector_drawable.dart +++ b/third_party/lib/vector_drawable.dart @@ -5,7 +5,8 @@ import 'package:flutter/widgets.dart'; import 'src/vector_painter.dart'; -enum PaintLocation { Foreground, Background } +/// Controls whether the widget draws in the foreground or background. +enum PaintLocation { foreground, background } /// Handles rendering the [DrawableRoot] from `future` to a [Canvas]. /// @@ -52,7 +53,7 @@ class VectorDrawableImage extends StatelessWidget { const VectorDrawableImage(this.future, this.size, {this.clipToViewBox = true, Key key, - this.paintLocation = PaintLocation.Background, + this.paintLocation = PaintLocation.background, this.errorWidgetBuilder, this.loadingPlaceholderBuilder, this.child}) @@ -79,10 +80,10 @@ class VectorDrawableImage extends StatelessWidget { new VectorPainter(snapShot.data, clipToViewBox: clipToViewBox); return new RepaintBoundary.wrap( CustomPaint( - painter: paintLocation == PaintLocation.Background + painter: paintLocation == PaintLocation.background ? painter : null, - foregroundPainter: paintLocation == PaintLocation.Foreground + foregroundPainter: paintLocation == PaintLocation.foreground ? painter : null, size: size, @@ -92,8 +93,6 @@ class VectorDrawableImage extends StatelessWidget { 0); } return localPlaceholder(context); - - // return const LimitedBox(); }, ); } From 8c1bac3d8265d65ec45da917a9872b39a017a7e6 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 20 May 2018 15:07:30 -0400 Subject: [PATCH 077/512] improve example --- third_party/example/main.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 09c6eb3942a3..4b48dd9f94eb 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -110,6 +110,7 @@ class _MyHomePageState extends State { if (color.value == 0xFF000000) { return Theme.of(context).iconTheme.color; } + return color; }, ), ); From 73f5571ff5e34d76840df7238e1c2cfac3d031ff Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 24 May 2018 09:31:09 -0400 Subject: [PATCH 078/512] Revert colorReplacer --- third_party/example/main.dart | 31 +++----------- third_party/lib/avd.dart | 6 +-- third_party/lib/src/svg/xml_parsers.dart | 40 +++++++------------ third_party/lib/src/svg_parser.dart | 8 ++-- third_party/lib/src/vector_painter.dart | 17 +------- third_party/lib/svg.dart | 51 ++++++++---------------- third_party/lib/vector_drawable.dart | 11 ++--- third_party/pubspec.lock | 2 +- 8 files changed, 50 insertions(+), 116 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 4b48dd9f94eb..4ad11c79fd45 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -18,14 +18,6 @@ const List assetNames = const [ 'assets/simple/style_attr.svg', 'assets/w3samples/aa.svg', 'assets/w3samples/alphachannel.svg', - 'assets/simple/ellipse.svg', - 'assets/simple/dash_path.svg', - 'assets/simple/nested_group.svg', - 'assets/wikimedia/chess_knight.svg', - 'assets/wikimedia/Ghostscript_Tiger.svg', -]; - -const List iconAssetNames = const [ 'assets/deborah_ufw/new-action-expander.svg', 'assets/deborah_ufw/new-camera.svg', 'assets/deborah_ufw/new-gif-button.svg', @@ -36,6 +28,11 @@ const List iconAssetNames = const [ 'assets/deborah_ufw/new-play-button.svg', 'assets/deborah_ufw/new-send-circle.svg', 'assets/deborah_ufw/numeric_25.svg', + 'assets/simple/ellipse.svg', + 'assets/simple/dash_path.svg', + 'assets/simple/nested_group.svg', + 'assets/wikimedia/chess_knight.svg', + 'assets/wikimedia/Ghostscript_Tiger.svg', ]; const List uriNames = const [ @@ -54,7 +51,6 @@ class MyApp extends StatelessWidget { title: 'Flutter Demo', theme: new ThemeData( primarySwatch: Colors.blue, - iconTheme: const IconThemeData(color: Colors.blueGrey) ), home: const MyHomePage(title: 'Flutter SVG Demo'), ); @@ -99,23 +95,6 @@ class _MyHomePageState extends State { ); } - for (String assetName in iconAssetNames) { - _painters.add( - new SvgImage.asset( - assetName, - new Size(_dimension, _dimension), - errorWidgetBuilder: customErrorBuilder, - colorReplacer: (Color color) { - print(color); - if (color.value == 0xFF000000) { - return Theme.of(context).iconTheme.color; - } - return color; - }, - ), - ); - } - for (String uriName in uriNames) { _painters.add( new SvgImage.network( diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 009a6108dfed..43a3ab3ddbd7 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -30,7 +30,7 @@ class AvdImage extends VectorDrawableImage { factory AvdImage.fromString(String svg, Size size, {Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.background, + PaintLocation paintLocation = PaintLocation.Background, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( @@ -49,7 +49,7 @@ class AvdImage extends VectorDrawableImage { AssetBundle bundle, String package, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.background, + PaintLocation paintLocation = PaintLocation.Background, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( @@ -67,7 +67,7 @@ class AvdImage extends VectorDrawableImage { {Map headers, Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.background, + PaintLocation paintLocation = PaintLocation.Background, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 89f0b299cda1..c25231a8a94f 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -59,8 +59,7 @@ void parseDefs(XmlElement el, DrawableDefinitionServer definitions) { for (XmlNode def in el.children) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { - definitions.addPaintServer( - buildUrlIri(def), parseGradient(def, definitions)); + definitions.addPaintServer(buildUrlIri(def), parseGradient(def)); } else if (def.name.local == 'clipPath') { definitions.addClipPath(buildUrlIri(def), parseClipPathDefinition(def)); } @@ -91,17 +90,11 @@ TileMode parseTileMode(XmlElement el) { } void parseStops( - List stops, - List colors, - List offsets, - DrawableDefinitionServer definitions, -) { + List stops, List colors, List offsets) { for (int i = 0; i < stops.length; i++) { final String rawOpacity = getAttribute(stops[i], 'stop-opacity', def: '1'); - colors[i] = definitions.replaceColor( - parseColor(getAttribute(stops[i], 'stop-color')) - .withOpacity(double.parse(rawOpacity)), - ); + colors[i] = parseColor(getAttribute(stops[i], 'stop-color')) + .withOpacity(double.parse(rawOpacity)); final String rawOffset = getAttribute(stops[i], 'offset'); offsets[i] = _parseDecimalOrPercentage(rawOffset); @@ -109,8 +102,7 @@ void parseStops( } /// Parses an SVG element into a [Paint]. -PaintServer parseLinearGradient( - XmlElement el, DrawableDefinitionServer definitions) { +PaintServer parseLinearGradient(XmlElement el) { final double x1 = _parseDecimalOrPercentage(getAttribute(el, 'x1', def: '0%')); final double x2 = @@ -125,7 +117,7 @@ PaintServer parseLinearGradient( final List colors = new List(stops.length); final List offsets = new List(stops.length); - parseStops(stops, colors, offsets, definitions); + parseStops(stops, colors, offsets); return (Rect bounds) { final Offset from = new Offset( @@ -150,8 +142,7 @@ PaintServer parseLinearGradient( } /// Parses a into a [Paint]. -PaintServer parseRadialGradient( - XmlElement el, DrawableDefinitionServer definitions) { +PaintServer parseRadialGradient(XmlElement el) { final String rawCx = getAttribute(el, 'cx', def: '50%'); final String rawCy = getAttribute(el, 'cy', def: '50%'); final TileMode spreadMethod = parseTileMode(el); @@ -160,7 +151,7 @@ PaintServer parseRadialGradient( final List colors = new List(stops.length); final List offsets = new List(stops.length); - parseStops(stops, colors, offsets, definitions); + parseStops(stops, colors, offsets); return (Rect bounds) { final double cx = _parseDecimalOrPercentage( @@ -242,11 +233,11 @@ List parseClipPath(XmlElement el, DrawableDefinitionServer definitions) { } /// Parses a or into a [Paint]. -PaintServer parseGradient(XmlElement el, DrawableDefinitionServer definitions) { +PaintServer parseGradient(XmlElement el) { if (el.name.local == 'linearGradient') { - return parseLinearGradient(el, definitions); + return parseLinearGradient(el); } else if (el.name.local == 'radialGradient') { - return parseRadialGradient(el, definitions); + return parseRadialGradient(el); } throw new StateError('Unknown gradient type ${el.name.local}'); } @@ -311,8 +302,7 @@ Paint parseStroke( final double opacity = rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); final Paint paint = new Paint() - ..color = - definitions.replaceColor(parseColor(rawStroke).withOpacity(opacity)) + ..color = parseColor(rawStroke).withOpacity(opacity) ..style = PaintingStyle.stroke; final String rawStrokeCap = getAttribute(el, 'stroke-linecap'); @@ -346,8 +336,7 @@ Paint parseFill(XmlElement el, Rect bounds, if (defaultFillIfNotSpecified == null) { return null; } - return new Paint() - ..color = definitions.replaceColor(defaultFillIfNotSpecified); + return new Paint()..color = defaultFillIfNotSpecified; } else if (rawFill == 'none') { return DrawableStyle.emptyPaint; } @@ -361,8 +350,7 @@ Paint parseFill(XmlElement el, Rect bounds, ? rawFill == 'none' ? 0.0 : 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); - final Color fill = - definitions.replaceColor(parseColor(rawFill).withOpacity(opacity)); + final Color fill = parseColor(rawFill).withOpacity(opacity); return new Paint() ..color = fill diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index ab3763bab9e7..1a70f4fca7ef 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -44,7 +44,7 @@ Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, return new DrawableNoop(el.name.local); } else if (el.name.local.endsWith('Gradient')) { definitions.addPaintServer( - 'url(#${getAttribute(el, 'id')})', parseGradient(el, definitions)); + 'url(#${getAttribute(el, 'id')})', parseGradient(el)); return new DrawableNoop(el.name.local); } else if (el.name.local == 'g' || el.name.local == 'a') { return parseSvgGroup(el, definitions, bounds, parentStyle); @@ -73,12 +73,12 @@ Drawable parseSvgText(XmlElement el, DrawableDefinitionServer definitions, textStyle: new TextStyle( fontFamily: getAttribute(el, 'font-family'), fontSize: double.parse(getAttribute(el, 'font-size', def: '55')), - color: definitions.replaceColor( - parseColor(getAttribute( + color: parseColor( + getAttribute( el, 'fill', def: getAttribute(el, 'stroke', def: 'black'), - )), + ), ), height: -1.0, ), diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 7255e504f130..7481aa79766d 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -1,16 +1,12 @@ import 'dart:typed_data'; import 'dart:ui'; +import 'package:path_drawing/path_drawing.dart'; import 'package:flutter/widgets.dart' hide TextStyle; import 'package:meta/meta.dart'; -import 'package:path_drawing/path_drawing.dart'; -/// Callback used to calculate gradients. typedef Paint PaintServer(Rect bounds); -/// Callback signature for color replacements. -typedef Color ColorReplacer(Color parsedColor); - /// Base interface for vector drawing. @immutable abstract class Drawable { @@ -168,20 +164,9 @@ class DrawableText implements Drawable { /// Contains reusable drawing elements that can be referenced by a String ID. class DrawableDefinitionServer { - DrawableDefinitionServer({ColorReplacer colorReplacer}) - : _colorReplacer = colorReplacer; - - final ColorReplacer _colorReplacer; final Map _paintServers = {}; final Map> _clipPaths = >{}; - Color replaceColor(Color original) { - if (_colorReplacer == null) { - return original; - } - return _colorReplacer(original) ?? original; - } - /// Attempt to lookup a pre-defined [Paint] by [id]. /// /// [id] and [bounds] must not be null. diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 1a3956fa5d8f..afc8e9fd8f68 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -32,14 +32,12 @@ class SvgImage extends VectorDrawableImage { factory SvgImage.fromString(String svg, Size size, {Key key, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.background, + PaintLocation paintLocation = PaintLocation.Background, Widget child, ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder, - ColorReplacer colorReplacer}) { + WidgetBuilder loadingPlaceholderBuilder}) { return new SvgImage._( - new Future.value( - fromSvgString(svg, size, colorReplacer: colorReplacer)), + new Future.value(fromSvgString(svg, size)), size, clipToViewBox: clipToViewBox, child: child, @@ -56,14 +54,12 @@ class SvgImage extends VectorDrawableImage { AssetBundle bundle, String package, bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.background, + PaintLocation paintLocation = PaintLocation.Background, Widget child, ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder, - ColorReplacer colorReplacer}) { + WidgetBuilder loadingPlaceholderBuilder}) { return new SvgImage._( - loadAsset(assetName, size, - bundle: bundle, package: package, colorReplacer: colorReplacer), + loadAsset(assetName, size, bundle: bundle, package: package), size, clipToViewBox: clipToViewBox, child: child, @@ -80,12 +76,11 @@ class SvgImage extends VectorDrawableImage { Key key, bool clipToViewBox = true, Widget child, - PaintLocation paintLocation = PaintLocation.background, + PaintLocation paintLocation = PaintLocation.Background, ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder, - ColorReplacer colorReplacer}) { + WidgetBuilder loadingPlaceholderBuilder}) { return new SvgImage._( - loadNetworkAsset(uri, size, colorReplacer: colorReplacer), + loadNetworkAsset(uri, size), size, clipToViewBox: clipToViewBox, child: child, @@ -99,16 +94,11 @@ class SvgImage extends VectorDrawableImage { /// Creates a [DrawableRoot] from a string of SVG data. [size] specifies the /// size of the coordinate space to draw to. -DrawableRoot fromSvgString( - String rawSvg, - Size size, { - ColorReplacer colorReplacer, -}) { +DrawableRoot fromSvgString(String rawSvg, Size size) { final XmlElement svg = xml.parse(rawSvg).rootElement; final Rect viewBox = parseViewBox(svg); //final Map paintServers = {}; - final DrawableDefinitionServer definitions = - new DrawableDefinitionServer(colorReplacer: colorReplacer); + final DrawableDefinitionServer definitions = new DrawableDefinitionServer(); final DrawableStyle style = parseStyle(svg, definitions, viewBox, null); final List children = svg.children @@ -135,29 +125,20 @@ DrawableRoot fromSvgString( /// Creates a [DrawableRoot] from a bundled asset. [size] specifies the size /// of the coordinate space to draw to. -Future loadAsset( - String assetName, - Size size, { - ColorReplacer colorReplacer, - AssetBundle bundle, - String package, -}) async { +Future loadAsset(String assetName, Size size, + {AssetBundle bundle, String package}) async { bundle ??= rootBundle; final String rawSvg = await bundle.loadString( package == null ? assetName : 'packages/$package/$assetName', ); - return fromSvgString(rawSvg, size, colorReplacer: colorReplacer); + return fromSvgString(rawSvg, size); } final HttpClient _httpClient = new HttpClient(); /// Creates a [DrawableRoot] from a network asset with an HTTP get request. /// [size] specifies the size of the coordinate space to draw to. -Future loadNetworkAsset( - String url, - Size size, { - ColorReplacer colorReplacer, -}) async { +Future loadNetworkAsset(String url, Size size) async { final Uri uri = Uri.base.resolve(url); final HttpClientRequest request = await _httpClient.getUrl(uri); final HttpClientResponse response = await request.close(); @@ -167,7 +148,7 @@ Future loadNetworkAsset( } final String rawSvg = await _consolidateHttpClientResponse(response); - return fromSvgString(rawSvg, size, colorReplacer: colorReplacer); + return fromSvgString(rawSvg, size); } Future _consolidateHttpClientResponse( diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart index fa89310b038c..a9dbdd642e11 100644 --- a/third_party/lib/vector_drawable.dart +++ b/third_party/lib/vector_drawable.dart @@ -5,8 +5,7 @@ import 'package:flutter/widgets.dart'; import 'src/vector_painter.dart'; -/// Controls whether the widget draws in the foreground or background. -enum PaintLocation { foreground, background } +enum PaintLocation { Foreground, Background } /// Handles rendering the [DrawableRoot] from `future` to a [Canvas]. /// @@ -53,7 +52,7 @@ class VectorDrawableImage extends StatelessWidget { const VectorDrawableImage(this.future, this.size, {this.clipToViewBox = true, Key key, - this.paintLocation = PaintLocation.background, + this.paintLocation = PaintLocation.Background, this.errorWidgetBuilder, this.loadingPlaceholderBuilder, this.child}) @@ -80,10 +79,10 @@ class VectorDrawableImage extends StatelessWidget { new VectorPainter(snapShot.data, clipToViewBox: clipToViewBox); return new RepaintBoundary.wrap( CustomPaint( - painter: paintLocation == PaintLocation.background + painter: paintLocation == PaintLocation.Background ? painter : null, - foregroundPainter: paintLocation == PaintLocation.foreground + foregroundPainter: paintLocation == PaintLocation.Foreground ? painter : null, size: size, @@ -93,6 +92,8 @@ class VectorDrawableImage extends StatelessWidget { 0); } return localPlaceholder(context); + + // return const LimitedBox(); }, ); } diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 1487413b6233..d6a60768cbb9 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -388,5 +388,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.55.0.flutter-43635d3372" + dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.55.0.flutter-97b6c2e09d" flutter: ">=0.3.6 <2.0.0" From 34a85aad7e924330aa98da94cab5ad05b5a87511 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 25 May 2018 00:13:59 -0400 Subject: [PATCH 079/512] Major refactor of widgets - WIP --- third_party/example/main.dart | 34 +- third_party/lib/avd.dart | 18 +- third_party/lib/flutter_svg.dart | 2 +- third_party/lib/src/avd_parser.dart | 2 +- third_party/lib/src/picture_provider.dart | 688 ++++++++++++++++++++++ third_party/lib/src/picture_stream.dart | 273 +++++++++ third_party/lib/src/render_picture.dart | 156 +++++ third_party/lib/src/svg/xml_parsers.dart | 2 +- third_party/lib/src/svg_parser.dart | 2 +- third_party/lib/src/vector_drawable.dart | 400 +++++++++++++ third_party/lib/src/vector_painter.dart | 397 +------------ third_party/lib/svg.dart | 195 ++++-- third_party/lib/vector_drawable.dart | 31 +- third_party/test/widget_svg_test.dart | 2 +- third_party/tool/gen_golden.dart | 4 +- 15 files changed, 1734 insertions(+), 472 deletions(-) create mode 100644 third_party/lib/src/picture_provider.dart create mode 100644 third_party/lib/src/picture_stream.dart create mode 100644 third_party/lib/src/render_picture.dart create mode 100644 third_party/lib/src/vector_drawable.dart diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 4ad11c79fd45..0197d7f139b6 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_svg/src/picture_provider.dart'; const List assetNames = const [ - 'assets/notfound.svg', + // 'assets/notfound.svg', 'assets/flutter_logo.svg', 'assets/dart.svg', 'assets/simple/clip_path_3.svg', @@ -36,9 +37,9 @@ const List assetNames = const [ ]; const List uriNames = const [ - 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', - 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', + // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', + // 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', ]; void main() => runApp(new MyApp()); @@ -66,7 +67,7 @@ class MyHomePage extends StatefulWidget { } class _MyHomePageState extends State { - final List _painters = []; + final List _painters = []; double _dimension; final ErrorWidgetBuilder customErrorBuilder = (FlutterErrorDetails details) { @@ -83,15 +84,21 @@ class _MyHomePageState extends State { @override void initState() { super.initState(); - _dimension = 365.0; + _dimension = 250.0; for (String assetName in assetNames) { _painters.add( - new SvgImage.asset( - assetName, - new Size(_dimension, _dimension), - errorWidgetBuilder: customErrorBuilder, - ), + // new FractionallySizedBox( + //size: new Size.square(_dimension), + // child: + new SvgPicture(new ExactAssetPicture(assetName), _dimension, _dimension), + // ), + + // _painters.add(new SvgImage.asset( + // assetName, + // new Size(_dimension, _dimension), + // errorWidgetBuilder: customErrorBuilder, + // ), ); } @@ -128,6 +135,11 @@ class _MyHomePageState extends State { setState(() => _dimension = val); }), // new FlutterLogo(size: _dimension), + // new Container( + // padding: const EdgeInsets.all(12.0), + // child: + + // ) new Expanded( child: new GridView.extent( shrinkWrap: true, diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 43a3ab3ddbd7..41c22733784c 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -9,19 +9,17 @@ import 'package:xml/xml.dart' as xml show parse; import 'src/avd/xml_parsers.dart'; import 'src/avd_parser.dart'; -import 'src/vector_painter.dart'; +import 'src/vector_drawable.dart'; import 'vector_drawable.dart'; /// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. class AvdImage extends VectorDrawableImage { const AvdImage._(Future future, Size size, - {bool clipToViewBox, - Key key, + {Key key, PaintLocation paintLocation, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) : super(future, size, - clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, @@ -29,14 +27,12 @@ class AvdImage extends VectorDrawableImage { factory AvdImage.fromString(String svg, Size size, {Key key, - bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( new Future.value(fromAvdString(svg, size)), size, - clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, @@ -48,14 +44,12 @@ class AvdImage extends VectorDrawableImage { {Key key, AssetBundle bundle, String package, - bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( loadAsset(assetName, size, bundle: bundle, package: package), size, - clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, @@ -66,14 +60,12 @@ class AvdImage extends VectorDrawableImage { factory AvdImage.network(String uri, Size size, {Map headers, Key key, - bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, ErrorWidgetBuilder errorWidgetBuilder, WidgetBuilder loadingPlaceholderBuilder}) { return new AvdImage._( loadNetworkAsset(uri, size), size, - clipToViewBox: clipToViewBox, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, diff --git a/third_party/lib/flutter_svg.dart b/third_party/lib/flutter_svg.dart index 0c29faec472f..3ed03a6b2508 100644 --- a/third_party/lib/flutter_svg.dart +++ b/third_party/lib/flutter_svg.dart @@ -1,3 +1,3 @@ -export 'src/vector_painter.dart'; +export 'src/vector_drawable.dart'; export 'svg.dart'; export 'vector_drawable.dart'; diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index dcdef0f3a0bc..e324196eba21 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -6,7 +6,7 @@ import 'package:vector_math/vector_math_64.dart'; import 'avd/xml_parsers.dart'; import 'utilities/xml.dart'; -import 'vector_painter.dart'; +import 'vector_drawable.dart'; class DrawableAvdRoot extends DrawableRoot { const DrawableAvdRoot(Rect viewBox, List children, diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart new file mode 100644 index 000000000000..ec84d2792bfe --- /dev/null +++ b/third_party/lib/src/picture_provider.dart @@ -0,0 +1,688 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:io'; +import 'dart:typed_data'; +import 'dart:ui' show Picture, Size, Locale, TextDirection, hashValues; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/services.dart'; + +// TODO: make this less SVG specific +import '../svg.dart'; +import 'picture_stream.dart'; +import 'vector_drawable.dart'; + +/// Configuration information passed to the [ImageProvider.resolve] method to +/// select a specific image. +/// +/// See also: +/// +/// * [createLocalImageConfiguration], which creates an [ImageConfiguration] +/// based on ambient configuration in a [Widget] environment. +/// * [ImageProvider], which uses [ImageConfiguration] objects to determine +/// which image to obtain. +@immutable +class ImageConfiguration { + /// Creates an object holding the configuration information for an [ImageProvider]. + /// + /// All the arguments are optional. Configuration information is merely + /// advisory and best-effort. + const ImageConfiguration({ + this.bundle, + this.devicePixelRatio, + this.locale, + this.textDirection, + this.size, + this.platform, + }); + + /// Creates an object holding the configuration information for an [ImageProvider]. + /// + /// All the arguments are optional. Configuration information is merely + /// advisory and best-effort. + ImageConfiguration copyWith({ + AssetBundle bundle, + double devicePixelRatio, + Locale locale, + TextDirection textDirection, + Size size, + String platform, + }) { + return new ImageConfiguration( + bundle: bundle ?? this.bundle, + devicePixelRatio: devicePixelRatio ?? this.devicePixelRatio, + locale: locale ?? this.locale, + textDirection: textDirection ?? this.textDirection, + size: size ?? this.size, + platform: platform ?? this.platform, + ); + } + + /// The preferred [AssetBundle] to use if the [ImageProvider] needs one and + /// does not have one already selected. + final AssetBundle bundle; + + /// The device pixel ratio where the image will be shown. + final double devicePixelRatio; + + /// The language and region for which to select the image. + final Locale locale; + + /// The reading direction of the language for which to select the image. + final TextDirection textDirection; + + /// The size at which the image will be rendered. + final Size size; + + /// The [TargetPlatform] for which assets should be used. This allows images + /// to be specified in a platform-neutral fashion yet use different assets on + /// different platforms, to match local conventions e.g. for color matching or + /// shadows. + final TargetPlatform platform; + + /// An image configuration that provides no additional information. + /// + /// Useful when resolving an [ImageProvider] without any context. + static const ImageConfiguration empty = const ImageConfiguration(); + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + final ImageConfiguration typedOther = other; + return typedOther.bundle == bundle && + typedOther.devicePixelRatio == devicePixelRatio && + typedOther.locale == locale && + typedOther.textDirection == textDirection && + typedOther.size == size && + typedOther.platform == platform; + } + + @override + int get hashCode => + hashValues(bundle, devicePixelRatio, locale, size, platform); + + @override + String toString() { + final StringBuffer result = new StringBuffer(); + result.write('ImageConfiguration('); + bool hasArguments = false; + if (bundle != null) { + if (hasArguments) { + result.write(', '); + } + result.write('bundle: $bundle'); + hasArguments = true; + } + if (devicePixelRatio != null) { + if (hasArguments) { + result.write(', '); + } + result.write('devicePixelRatio: ${devicePixelRatio.toStringAsFixed(1)}'); + hasArguments = true; + } + if (locale != null) { + if (hasArguments) { + result.write(', '); + } + result.write('locale: $locale'); + hasArguments = true; + } + if (textDirection != null) { + if (hasArguments) { + result.write(', '); + } + result.write('textDirection: $textDirection'); + hasArguments = true; + } + if (size != null) { + if (hasArguments) { + result.write(', '); + } + result.write('size: $size'); + hasArguments = true; + } + if (platform != null) { + if (hasArguments) { + result.write(', '); + } + result.write('platform: ${describeEnum(platform)}'); + hasArguments = true; + } + result.write(')'); + return result.toString(); + } +} + +/// Identifies an image without committing to the precise final asset. This +/// allows a set of images to be identified and for the precise image to later +/// be resolved based on the environment, e.g. the device pixel ratio. +/// +/// To obtain an [PictureStream] from an [ImageProvider], call [resolve], +/// passing it an [ImageConfiguration] object. +/// +/// [ImageProvider] uses the global [imageCache] to cache images. +/// +/// The type argument `T` is the type of the object used to represent a resolved +/// configuration. This is also the type used for the key in the image cache. It +/// should be immutable and implement the [==] operator and the [hashCode] +/// getter. Subclasses should subclass a variant of [ImageProvider] with an +/// explicit `T` type argument. +/// +/// The type argument does not have to be specified when using the type as an +/// argument (where any image provider is acceptable). +/// +/// The following image formats are supported: {@macro flutter.dart:ui.imageFormats} +/// +/// ## Sample code +/// +/// The following shows the code required to write a widget that fully conforms +/// to the [ImageProvider] and [Widget] protocols. (It is essentially a +/// bare-bones version of the [widgets.Image] widget.) +/// +/// ```dart +/// class MyImage extends StatefulWidget { +/// const MyImage({ +/// Key key, +/// @required this.imageProvider, +/// }) : assert(imageProvider != null), +/// super(key: key); +/// +/// final ImageProvider imageProvider; +/// +/// @override +/// _MyImageState createState() => new _MyImageState(); +/// } +/// +/// class _MyImageState extends State { +/// PictureStream _PictureStream; +/// ImageInfo _imageInfo; +/// +/// @override +/// void didChangeDependencies() { +/// super.didChangeDependencies(); +/// // We call _getImage here because createLocalImageConfiguration() needs to +/// // be called again if the dependencies changed, in case the changes relate +/// // to the DefaultAssetBundle, MediaQuery, etc, which that method uses. +/// _getImage(); +/// } +/// +/// @override +/// void didUpdateWidget(MyImage oldWidget) { +/// super.didUpdateWidget(oldWidget); +/// if (widget.imageProvider != oldWidget.imageProvider) +/// _getImage(); +/// } +/// +/// void _getImage() { +/// final PictureStream oldPictureStream = _PictureStream; +/// _PictureStream = widget.imageProvider.resolve(createLocalImageConfiguration(context)); +/// if (_PictureStream.key != oldPictureStream?.key) { +/// // If the keys are the same, then we got the same image back, and so we don't +/// // need to update the listeners. If the key changed, though, we must make sure +/// // to switch our listeners to the new image stream. +/// oldPictureStream?.removeListener(_updateImage); +/// _PictureStream.addListener(_updateImage); +/// } +/// } +/// +/// void _updateImage(ImageInfo imageInfo, bool synchronousCall) { +/// setState(() { +/// // Trigger a build whenever the image changes. +/// _imageInfo = imageInfo; +/// }); +/// } +/// +/// @override +/// void dispose() { +/// _PictureStream.removeListener(_updateImage); +/// super.dispose(); +/// } +/// +/// @override +/// Widget build(BuildContext context) { +/// return new RawImage( +/// image: _imageInfo?.image, // this is a dart:ui Image object +/// scale: _imageInfo?.scale ?? 1.0, +/// ); +/// } +/// } +/// ``` +@optionalTypeArgs +abstract class PictureProvider { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. + const PictureProvider(); + + /// Resolves this image provider using the given `configuration`, returning + /// an [PictureStream]. + /// + /// This is the public entry-point of the [ImageProvider] class hierarchy. + /// + /// Subclasses should implement [obtainKey] and [load], which are used by this + /// method. + PictureStream resolve(PictureInfo picture) { + // assert(picture != null); + final PictureStream stream = new PictureStream(); + T obtainedKey; + obtainKey().then((T key) { + obtainedKey = key; + stream.setCompleter(load(key)); + // stream.setCompleter(PaintingBinding.instance.imageCache + // .putIfAbsent(key, () => load(key))); + }).catchError((dynamic exception, StackTrace stack) async { + FlutterError.reportError(new FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'services library', + context: 'while resolving an image', + silent: true, // could be a network error or whatnot + informationCollector: (StringBuffer information) { + information.writeln('Image provider: $this'); + if (obtainedKey != null) + information.writeln('Image key: $obtainedKey'); + })); + return null; + }); + return stream; + } + + /// Converts an ImageProvider's settings plus an ImageConfiguration to a key + /// that describes the precise image to load. + /// + /// The type of the key is determined by the subclass. It is a value that + /// unambiguously identifies the image (_including its scale_) that the [load] + /// method will fetch. Different [ImageProvider]s given the same constructor + /// arguments and [ImageConfiguration] objects should return keys that are + /// '==' to each other (possibly by using a class for the key that itself + /// implements [==]). + @protected + Future obtainKey(); + + /// Converts a key into an [PictureStreamCompleter], and begins fetching the + /// image. + @protected + PictureStreamCompleter load(T key); + + @override + String toString() => '$runtimeType()'; +} + +/// Key for the image obtained by an [AssetImage] or [ExactAssetImage]. +/// +/// This is used to identify the precise resource in the [imageCache]. +@immutable +class AssetBundlePictureKey { + /// Creates the key for an [AssetPicture] or [AssetBundlePictureProvider]. + /// + /// The arguments must not be null. + const AssetBundlePictureKey({@required this.bundle, @required this.name}) + : assert(bundle != null), + assert(name != null); + + /// The bundle from which the image will be obtained. + /// + /// The image is obtained by calling [AssetBundle.load] on the given [bundle] + /// using the key given by [name]. + final AssetBundle bundle; + + /// The key to use to obtain the resource from the [bundle]. This is the + /// argument passed to [AssetBundle.load]. + final String name; + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + final AssetBundlePictureKey typedOther = other; + return bundle == typedOther.bundle && name == typedOther.name; + } + + @override + int get hashCode => hashValues(bundle, name); + + @override + String toString() => '$runtimeType(bundle: $bundle, name: "$name")'; +} + +/// A subclass of [ImageProvider] that knows about [AssetBundle]s. +/// +/// This factors out the common logic of [AssetBundle]-based [ImageProvider] +/// classes, simplifying what subclasses must implement to just [obtainKey]. +abstract class AssetBundlePictureProvider + extends PictureProvider { + /// Abstract const constructor. This constructor enables subclasses to provide + /// const constructors so that they can be used in const expressions. + const AssetBundlePictureProvider(); + + /// Converts a key into an [PictureStreamCompleter], and begins fetching the + /// image using [loadAsync]. + @override + PictureStreamCompleter load(AssetBundlePictureKey key) { + return new OneFramePictureStreamCompleter(loadAsync(key), + informationCollector: (StringBuffer information) { + information.writeln('Image provider: $this'); + information.write('Image key: $key'); + }); + } + + /// Fetches the image from the asset bundle, decodes it, and returns a + /// corresponding [ImageInfo] object. + /// + /// This function is used by [load]. + @protected + Future loadAsync(AssetBundlePictureKey key) async { + final String data = await key.bundle.loadString(key.name); + if (data == null) { + throw 'Unable to read data'; + } + final DrawableRoot root = fromSvgString(data); + return new PictureInfo(picture: root.toPicture(), viewBox: root.viewBox); + } +} + +/// Fetches the given URL from the network, associating it with the given scale. +/// +/// The image will be cached regardless of cache headers from the server. +/// +/// See also: +/// +/// * [Image.network] for a shorthand of an [Image] widget backed by [NetworkImage]. +// TODO(ianh): Find some way to honour cache headers to the extent that when the +// last reference to an image is released, we proactively evict the image from +// our cache if the headers describe the image as having expired at that point. +class NetworkPicture extends PictureProvider { + /// Creates an object that fetches the image at the given URL. + /// + /// The arguments must not be null. + const NetworkPicture(this.url, {this.headers}) : assert(url != null); + + /// The URL from which the image will be fetched. + final String url; + + /// The HTTP headers that will be used with [HttpClient.get] to fetch image from network. + final Map headers; + + @override + Future obtainKey() { + return new SynchronousFuture(this); + } + + @override + PictureStreamCompleter load(NetworkPicture key) { + return new OneFramePictureStreamCompleter(loadAsync(key), + informationCollector: (StringBuffer information) { + information.writeln('Image provider: $this'); + information.write('Image key: $key'); + }); + } + + Future loadAsync(NetworkPicture key) async { + assert(key == this); + final DrawableRoot root = await loadNetworkAsset(key.url); + + return new PictureInfo(picture: root.toPicture(), viewBox: root.viewBox); + } + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + final NetworkPicture typedOther = other; + return url == typedOther.url; + } + + @override + int get hashCode => url.hashCode; + + @override + String toString() => '$runtimeType("$url", $headers)'; +} + +/// Decodes the given [File] object as an image, associating it with the given +/// scale. +/// +/// See also: +/// +/// * [Image.file] for a shorthand of an [Image] widget backed by [FileImage]. +class FileImage extends PictureProvider { + /// Creates an object that decodes a [File] as an image. + /// + /// The arguments must not be null. + const FileImage(this.file) : assert(file != null); + + /// The file to decode into an image. + final File file; + + @override + Future obtainKey() { + return new SynchronousFuture(this); + } + + @override + PictureStreamCompleter load(FileImage key) { + return new OneFramePictureStreamCompleter(loadAsync(key), + informationCollector: (StringBuffer information) { + information.writeln('Path: ${file?.path}'); + }); + } + + Future loadAsync(FileImage key) async { + assert(key == this); + + final String data = await file.readAsString(); + if (data == null || data.isEmpty) { + return null; + } + + final DrawableRoot root = fromSvgString(data); + return new PictureInfo(picture: root.toPicture(), viewBox: root.viewBox); + } + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + final FileImage typedOther = other; + return file?.path == typedOther.file?.path; + } + + @override + int get hashCode => file?.path?.hashCode; + + @override + String toString() => '$runtimeType("${file?.path}")'; +} + +/// Decodes the given [String] buffer as an image, associating it with the +/// given scale. +/// +/// The provided [bytes] buffer should not be changed after it is provided +/// to a [MemoryImage]. To provide an [PictureStream] that represents an image +/// that changes over time, consider creating a new subclass of [ImageProvider] +/// whose [load] method returns a subclass of [PictureStreamCompleter] that can +/// handle providing multiple images. +/// +/// See also: +/// +/// * [Image.memory] for a shorthand of an [Image] widget backed by [MemoryImage]. +class MemoryPicture extends PictureProvider { + /// Creates an object that decodes a [Uint8List] buffer as an image. + /// + /// The arguments must not be null. + const MemoryPicture(this.bytes) : assert(bytes != null); + + /// The bytes to decode into an image. + final String bytes; + + @override + Future obtainKey() { + return new SynchronousFuture(this); + } + + @override + PictureStreamCompleter load(MemoryPicture key) { + return new OneFramePictureStreamCompleter(loadAsync(key)); + } + + Future loadAsync(MemoryPicture key) { + assert(key == this); + final DrawableRoot root = fromSvgString(bytes); + return Future.value( + new PictureInfo(picture: root.toPicture(), viewBox: root.viewBox), + ); + } + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + final MemoryPicture typedOther = other; + return bytes == typedOther.bytes; + } + + @override + int get hashCode => bytes.hashCode; + + @override + String toString() => '$runtimeType(${describeIdentity(bytes)})'; +} + +/// Fetches an image from an [AssetBundle], associating it with the given scale. +/// +/// This implementation requires an explicit final [assetName] and [scale] on +/// construction, and ignores the device pixel ratio and size in the +/// configuration passed into [resolve]. For a resolution-aware variant that +/// uses the configuration to pick an appropriate image based on the device +/// pixel ratio and size, see [AssetImage]. +/// +/// ## Fetching assets +/// +/// When fetching an image provided by the app itself, use the [assetName] +/// argument to name the asset to choose. For instance, consider a directory +/// `icons` with an image `heart.png`. First, the [pubspec.yaml] of the project +/// should specify its assets in the `flutter` section: +/// +/// ```yaml +/// flutter: +/// assets: +/// - icons/heart.png +/// ``` +/// +/// Then, to fetch the image and associate it with scale `1.5`, use +/// +/// ```dart +/// new AssetImage('icons/heart.png', scale: 1.5) +/// ``` +/// +///## Assets in packages +/// +/// To fetch an asset from a package, the [package] argument must be provided. +/// For instance, suppose the structure above is inside a package called +/// `my_icons`. Then to fetch the image, use: +/// +/// ```dart +/// new AssetImage('icons/heart.png', scale: 1.5, package: 'my_icons') +/// ``` +/// +/// Assets used by the package itself should also be fetched using the [package] +/// argument as above. +/// +/// If the desired asset is specified in the `pubspec.yaml` of the package, it +/// is bundled automatically with the app. In particular, assets used by the +/// package itself must be specified in its `pubspec.yaml`. +/// +/// A package can also choose to have assets in its 'lib/' folder that are not +/// specified in its `pubspec.yaml`. In this case for those images to be +/// bundled, the app has to specify which ones to include. For instance a +/// package named `fancy_backgrounds` could have: +/// +/// ``` +/// lib/backgrounds/background1.png +/// lib/backgrounds/background2.png +/// lib/backgrounds/background3.png +///``` +/// +/// To include, say the first image, the `pubspec.yaml` of the app should specify +/// it in the `assets` section: +/// +/// ```yaml +/// assets: +/// - packages/fancy_backgrounds/backgrounds/background1.png +/// ``` +/// +/// Note that the `lib/` is implied, so it should not be included in the asset +/// path. +/// +/// See also: +/// +/// * [Image.asset] for a shorthand of an [Image] widget backed by +/// [ExactAssetImage] when using a scale. +class ExactAssetPicture extends AssetBundlePictureProvider { + /// Creates an object that fetches the given image from an asset bundle. + /// + /// The [assetName] and [scale] arguments must not be null. The [scale] arguments + /// defaults to 1.0. The [bundle] argument may be null, in which case the + /// bundle provided in the [ImageConfiguration] passed to the [resolve] call + /// will be used instead. + /// + /// The [package] argument must be non-null when fetching an asset that is + /// included in a package. See the documentation for the [ExactAssetImage] class + /// itself for details. + const ExactAssetPicture( + this.assetName, { + this.bundle, + this.package, + }) : assert(assetName != null); + + /// The name of the asset. + final String assetName; + + /// The key to use to obtain the resource from the [bundle]. This is the + /// argument passed to [AssetBundle.load]. + String get keyName => + package == null ? assetName : 'packages/$package/$assetName'; + + /// The bundle from which the image will be obtained. + /// + /// If the provided [bundle] is null, the bundle provided in the + /// [ImageConfiguration] passed to the [resolve] call will be used instead. If + /// that is also null, the [rootBundle] is used. + /// + /// The image is obtained by calling [AssetBundle.load] on the given [bundle] + /// using the key given by [keyName]. + final AssetBundle bundle; + + /// The name of the package from which the image is included. See the + /// documentation for the [ExactAssetImage] class itself for details. + final String package; + + @override + Future obtainKey() { + return new SynchronousFuture( + new AssetBundlePictureKey(bundle: bundle ?? rootBundle, name: keyName)); + } + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + final ExactAssetPicture typedOther = other; + return keyName == typedOther.keyName && bundle == typedOther.bundle; + } + + @override + int get hashCode => hashValues(keyName, bundle); + + @override + String toString() => '$runtimeType(name: "$keyName", bundle: $bundle)'; +} diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart new file mode 100644 index 000000000000..0b1e5b92371f --- /dev/null +++ b/third_party/lib/src/picture_stream.dart @@ -0,0 +1,273 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:ui' show Picture, Rect, hashValues; + +import 'package:flutter/foundation.dart'; + +@immutable +class PictureInfo { + const PictureInfo({@required this.picture, @required this.viewBox}) + : assert(picture != null), + assert(viewBox != null); + + /// The raw picture. + /// + /// This is the object to pass to the [Canvas.drawPicture] when painting. + final Picture picture; + + /// The viewBox enclosing the coordinates used in the picture. + final Rect viewBox; + + @override + String toString() => '$picture $viewBox'; + + @override + int get hashCode => hashValues(picture, viewBox); + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) { + return false; + } + final PictureInfo typedOther = other; + return typedOther.picture == picture && typedOther.viewBox == viewBox; + } +} + +/// Signature for callbacks reporting that an image is available. +/// +/// Used by [ImageStream]. +/// +/// The `synchronousCall` argument is true if the listener is being invoked +/// during the call to addListener. This can be useful if, for example, +/// [ImageStream.addListener] is invoked during a frame, so that a new rendering +/// frame is requested if the call was asynchronous (after the current frame) +/// and no rendering frame is requested if the call was synchronous (within the +/// same stack frame as the call to [ImageStream.addListener]). +typedef void PictureListener(PictureInfo image, bool synchronousCall); + +/// A handle to an image resource. +/// +/// ImageStream represents a handle to a [dart:ui.Image] object and its scale +/// (together represented by an [ImageInfo] object). The underlying image object +/// might change over time, either because the image is animating or because the +/// underlying image resource was mutated. +/// +/// ImageStream objects can also represent an image that hasn't finished +/// loading. +/// +/// ImageStream objects are backed by [PictureStreamCompleter] objects. +/// +/// See also: +/// +/// * [ImageProvider], which has an example that includes the use of an +/// [ImageStream] in a [Widget]. +class PictureStream extends Diagnosticable { + /// Create an initially unbound image stream. + /// + /// Once an [PictureStreamCompleter] is available, call [setCompleter]. + PictureStream(); + + /// The completer that has been assigned to this image stream. + /// + /// Generally there is no need to deal with the completer directly. + PictureStreamCompleter get completer => _completer; + PictureStreamCompleter _completer; + + List _listeners; + + /// Assigns a particular [PictureStreamCompleter] to this [ImageStream]. + /// + /// This is usually done automatically by the [ImageProvider] that created the + /// [ImageStream]. + /// + /// This method can only be called once per stream. To have an [ImageStream] + /// represent multiple images over time, assign it a completer that + /// completes several images in succession. + void setCompleter(PictureStreamCompleter value) { + assert(_completer == null); + _completer = value; + if (_listeners != null) { + final List initialListeners = _listeners; + _listeners = null; + initialListeners.forEach(_completer.addListener); + } + } + + /// Adds a listener callback that is called whenever a new concrete [ImageInfo] + /// object is available. If a concrete image is already available, this object + /// will call the listener synchronously. + /// + /// If the assigned [completer] completes multiple images over its lifetime, + /// this listener will fire multiple times. + /// + /// The listener will be passed a flag indicating whether a synchronous call + /// occurred. If the listener is added within a render object paint function, + /// then use this flag to avoid calling [RenderObject.markNeedsPaint] during + /// a paint. + void addListener(PictureListener listener) { + if (_completer != null) { + return _completer.addListener(listener); + } + _listeners ??= []; + _listeners.add(listener); + } + + /// Stop listening for new concrete [ImageInfo] objects. + void removeListener(PictureListener listener) { + if (_completer != null) { + return _completer.removeListener(listener); + } + assert(_listeners != null); + _listeners.remove(listener); + } + + /// Returns an object which can be used with `==` to determine if this + /// [ImageStream] shares the same listeners list as another [ImageStream]. + /// + /// This can be used to avoid unregistering and reregistering listeners after + /// calling [ImageProvider.resolve] on a new, but possibly equivalent, + /// [ImageProvider]. + /// + /// The key may change once in the lifetime of the object. When it changes, it + /// will go from being different than other [ImageStream]'s keys to + /// potentially being the same as others'. No notification is sent when this + /// happens. + Object get key => _completer != null ? _completer : this; + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(new ObjectFlagProperty( + 'completer', + _completer, + ifPresent: _completer?.toStringShort(), + ifNull: 'unresolved', + )); + properties.add(new ObjectFlagProperty>( + 'listeners', + _listeners, + ifPresent: + '${_listeners?.length} listener${_listeners?.length == 1 ? "" : "s" }', + ifNull: 'no listeners', + level: _completer != null ? DiagnosticLevel.hidden : DiagnosticLevel.info, + )); + _completer?.debugFillProperties(properties); + } +} + +/// Base class for those that manage the loading of [dart:ui.Image] objects for +/// [ImageStream]s. +/// +/// [ImageStreamListener] objects are rarely constructed directly. Generally, an +/// [ImageProvider] subclass will return an [ImageStream] and automatically +/// configure it with the right [PictureStreamCompleter] when possible. +abstract class PictureStreamCompleter extends Diagnosticable { + final List _listeners = []; + PictureInfo _current; + + /// Adds a listener callback that is called whenever a new concrete [ImageInfo] + /// object is available. If a concrete image is already available, this object + /// will call the listener synchronously. + /// + /// If the [PictureStreamCompleter] completes multiple images over its lifetime, + /// this listener will fire multiple times. + /// + /// The listener will be passed a flag indicating whether a synchronous call + /// occurred. If the listener is added within a render object paint function, + /// then use this flag to avoid calling [RenderObject.markNeedsPaint] during + /// a paint. + void addListener(PictureListener listener) { + _listeners.add(listener); + if (_current != null) { + try { + listener(_current, true); + } catch (exception, stack) { + _handleImageError( + 'by a synchronously-called image listener', exception, stack); + } + } + } + + /// Stop listening for new concrete [ImageInfo] objects. + void removeListener(PictureListener listener) { + _listeners.remove(listener); + } + + /// Calls all the registered listeners to notify them of a new image. + @protected + void setImage(PictureInfo image) { + _current = image; + if (_listeners.isEmpty) { + return; + } + final List localListeners = + new List.from(_listeners); + for (PictureListener listener in localListeners) { + try { + listener(image, false); + } catch (exception, stack) { + _handleImageError('by an image listener', exception, stack); + } + } + } + + void _handleImageError(String context, dynamic exception, dynamic stack) { + FlutterError.reportError(new FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'image resource service', + context: context)); + } + + /// Accumulates a list of strings describing the object's state. Subclasses + /// should override this to have their information included in [toString]. + @override + void debugFillProperties(DiagnosticPropertiesBuilder description) { + super.debugFillProperties(description); + description.add(new DiagnosticsProperty('current', _current, + ifNull: 'unresolved', showName: false)); + description.add(new ObjectFlagProperty>( + 'listeners', + _listeners, + ifPresent: + '${_listeners?.length} listener${_listeners?.length == 1 ? "" : "s" }', + )); + } +} + +/// Manages the loading of [dart:ui.Image] objects for static [ImageStream]s (those +/// with only one frame). +class OneFramePictureStreamCompleter extends PictureStreamCompleter { + /// Creates a manager for one-frame [ImageStream]s. + /// + /// The image resource awaits the given [Future]. When the future resolves, + /// it notifies the [PictureListener]s that have been registered with + /// [addListener]. + /// + /// The [InformationCollector], if provided, is invoked if the given [Future] + /// resolves with an error, and can be used to supplement the reported error + /// message (for example, giving the image's URL). + /// + /// Errors are reported using [FlutterError.reportError] with the `silent` + /// argument on [FlutterErrorDetails] set to true, meaning that by default the + /// message is only dumped to the console in debug mode (see [new + /// FlutterErrorDetails]). + OneFramePictureStreamCompleter(Future image, + {InformationCollector informationCollector}) + : assert(image != null) { + image.then(setImage, onError: (dynamic error, StackTrace stack) { + FlutterError.reportError(new FlutterErrorDetails( + exception: error, + stack: stack, + library: 'SVG', + context: 'resolving a single-frame picture stream', + informationCollector: informationCollector, + silent: true, + )); + }); + } +} diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart new file mode 100644 index 000000000000..03c17df2b1c5 --- /dev/null +++ b/third_party/lib/src/render_picture.dart @@ -0,0 +1,156 @@ +import 'package:flutter/widgets.dart'; +import 'package:meta/meta.dart'; + +import 'picture_stream.dart'; + +@immutable +class RawPicture extends LeafRenderObjectWidget { + const RawPicture( + this.picture, { + Key key, + this.width, + this.height, + this.matchTextDirection = false, + this.textDirection, + }) : super(key: key); + + final PictureInfo picture; + final double width; + final double height; + final bool matchTextDirection; + final TextDirection textDirection; + + @override + RenderPicture createRenderObject(BuildContext context) { + // TODO: implement createRenderObject + return new RenderPicture( + picture: picture, + matchTextDirection: matchTextDirection, + textDirection: textDirection); + } + + @override + void updateRenderObject(BuildContext context, RenderPicture renderObject) { + renderObject + ..picture = picture + ..matchTextDirection = matchTextDirection + ..textDirection = textDirection; + } +} + +class RenderPicture extends RenderBox { + RenderPicture({ + PictureInfo picture, + bool matchTextDirection: false, + TextDirection textDirection, + }) : _picture = picture, + _matchTextDirection = matchTextDirection, + _textDirection = textDirection; + + /// Whether to paint the image in the direction of the [TextDirection]. + /// + /// If this is true, then in [TextDirection.ltr] contexts, the image will be + /// drawn with its origin in the top left (the "normal" painting direction for + /// images); and in [TextDirection.rtl] contexts, the image will be drawn with + /// a scaling factor of -1 in the horizontal direction so that the origin is + /// in the top right. + /// + /// This is occasionally used with images in right-to-left environments, for + /// images that were designed for left-to-right locales. Be careful, when + /// using this, to not flip images with integral shadows, text, or other + /// effects that will look incorrect when flipped. + /// + /// If this is set to true, [textDirection] must not be null. + bool get matchTextDirection => _matchTextDirection; + bool _matchTextDirection; + set matchTextDirection(bool value) { + assert(value != null); + if (value == _matchTextDirection) { + return; + } + _matchTextDirection = value; + markNeedsPaint(); + } + + bool get _flipHorizontally => + _matchTextDirection && _textDirection == TextDirection.rtl; + + /// The text direction with which to resolve [alignment]. + /// + /// This may be changed to null, but only after the [alignment] and + /// [matchTextDirection] properties have been changed to values that do not + /// depend on the direction. + TextDirection get textDirection => _textDirection; + TextDirection _textDirection; + set textDirection(TextDirection value) { + if (_textDirection == value) { + return; + } + _textDirection = value; + markNeedsPaint(); + } + + PictureInfo _picture; + PictureInfo get picture => _picture; + set picture(PictureInfo val) { + if (val == picture) { + return; + } + _picture = val; + markNeedsPaint(); + } + + @override + bool hitTestSelf(Offset position) => true; + + @override + bool get sizedByParent => true; + + @override + void performResize() { + size = constraints.smallest; + } + + @override + void paint(PaintingContext context, Offset offset) { + if (picture == null || size == null || size == Size.zero) { + return; + } + context.canvas.save(); + context.canvas.translate(offset.dx, offset.dy); + if (_flipHorizontally) { + final double dx = -(offset.dx + size.width / 2.0); + context.canvas.translate(-dx, 0.0); + context.canvas.scale(-1.0, 1.0); + } + + // this is sometimes useful for debugging, will remove + // context.canvas.drawRect( + // Offset.zero & size, + // new Paint() + // ..color = const Color(0xFFFA0000) + // ..style = PaintingStyle.stroke); + + scaleCanvasToViewBox(context.canvas, size, picture.viewBox); + context.canvas.clipRect(picture.viewBox); + context.canvas.drawPicture(picture.picture); + context.canvas.restore(); + } +} + +void scaleCanvasToViewBox(Canvas canvas, Size desiredSize, Rect viewBox) { + final double xscale = desiredSize.width / viewBox.size.width; + final double yscale = desiredSize.height / viewBox.size.height; + + if (xscale == yscale) { + canvas.scale(xscale, yscale); + } else if (xscale < yscale) { + final double xtranslate = (viewBox.size.width - viewBox.size.height) / 2; + canvas.scale(xscale, xscale); + canvas.translate(0.0, xtranslate); + } else { + final double ytranslate = (viewBox.size.height - viewBox.size.width) / 2; + canvas.scale(yscale, yscale); + canvas.translate(ytranslate, 0.0); + } +} diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index c25231a8a94f..337f977c7496 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -5,7 +5,7 @@ import 'package:vector_math/vector_math_64.dart'; import 'package:xml/xml.dart'; import '../utilities/xml.dart'; -import '../vector_painter.dart'; +import '../vector_drawable.dart'; import 'colors.dart'; import 'parsers.dart'; diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 1a70f4fca7ef..a818a9b57abe 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -7,7 +7,7 @@ import 'svg/colors.dart'; import 'svg/parsers.dart'; import 'svg/xml_parsers.dart'; import 'utilities/xml.dart'; -import 'vector_painter.dart'; +import 'vector_drawable.dart'; /// An SVG Shape element that will be drawn to the canvas. class DrawableSvgShape extends DrawableShape { diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart new file mode 100644 index 000000000000..6b88bc807dc0 --- /dev/null +++ b/third_party/lib/src/vector_drawable.dart @@ -0,0 +1,400 @@ +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:path_drawing/path_drawing.dart'; +import 'package:flutter/widgets.dart' hide TextStyle; +import 'package:meta/meta.dart'; + +typedef Paint PaintServer(Rect bounds); + +/// Base interface for vector drawing. +@immutable +abstract class Drawable { + /// Whether this [Drawable] would be visible if [draw]n. + bool get hasDrawableContent; + + /// Draws the contents or children of this [Drawable] to the `canvas`, using + /// the `parentPaint` to optionally override the child's paint. + void draw(Canvas canvas); +} + +/// Styling information for vector drawing. +/// +/// Contains [Paint], [Path], dashing, transform, and text styling information. +@immutable +class DrawableStyle { + /// This should be used where 'stroke' or 'fill' are 'none'. + /// + /// This will not result in a drawing operation, but will clear out + /// inheritance. Modifying this paint should not result in any changes to + /// the image, but it should not be modified. + static final Paint emptyPaint = new Paint(); + + /// Used where 'dasharray' is 'none' + /// + /// This will not result in a drawing operation, but will clear out + /// inheritence. + static final CircularIntervalList emptyDashArray = + new CircularIntervalList(const []); + + /// If not `null` and not `identical` with [emptyPaint], will result in a stroke + /// for the rendered [DrawableShape]. Drawn __after__ the [fill]. + final Paint stroke; + + /// The dashing array to use for the [stroke], if any. + final CircularIntervalList dashArray; + + /// The [DashOffset] to use for where to begin the [dashArray]. + final DashOffset dashOffset; + + /// If not `null` and not `identical` with [emptyPaint], will result in a fill + /// for the rendered [DrawableShape]. Drawn __before__ the [stroke]. + final Paint fill; + + /// The 4x4 matrix ([Matrix4]) for a transform, if any. + final Float64List transform; + + final TextStyle textStyle; + + /// The fill rule to use for this path. + final PathFillType pathFillType; + + /// The clip to apply, if any. + final List clipPath; + + /// Controls inheriting opacity. Will be averaged with child opacity. + final double groupOpacity; + + const DrawableStyle( + {this.stroke, + this.dashArray, + this.dashOffset, + this.fill, + this.transform, + this.textStyle, + this.pathFillType, + this.groupOpacity, + this.clipPath}); + + /// Creates a new [DrawableStyle] if `parent` is not null, filling in any null properties on + /// this with the properties from other (except [groupOpacity], which is averaged). + static DrawableStyle mergeAndBlend(DrawableStyle parent, + {Paint fill, + Paint stroke, + CircularIntervalList dashArray, + DashOffset dashOffset, + Float64List transform, + TextStyle textStyle, + PathFillType pathFillType, + double groupOpacity, + List clipPath}) { + final DrawableStyle ret = new DrawableStyle( + fill: fill ?? parent?.fill, + stroke: stroke ?? parent?.stroke, + dashArray: dashArray ?? parent?.dashArray, + dashOffset: dashOffset ?? parent?.dashOffset, + // transforms aren't inherited because they're applied to canvas with save/restore + // that wraps any potential children + transform: transform, + textStyle: textStyle ?? parent?.textStyle, + pathFillType: pathFillType ?? parent?.pathFillType, + groupOpacity: mergeOpacity(groupOpacity, parent?.groupOpacity), + // clips don't make sense to inherit - applied to canvas with save/restore + // that wraps any potential children + clipPath: clipPath, + ); + + if (ret.fill != null) { + ret.fill.color = ret.fill.color.withOpacity(ret.fill.color.opacity == 1.0 + ? ret.groupOpacity ?? 1.0 + : mergeOpacity(ret.groupOpacity, ret.fill.color.opacity)); + } + if (ret.stroke != null) { + ret.stroke.color = ret.stroke.color.withOpacity( + ret.stroke.color.opacity == 1.0 + ? ret.groupOpacity ?? 1.0 + : mergeOpacity(ret.groupOpacity, ret.stroke.color.opacity)); + } + + return ret; + } + + /// Averages [back] and [front]. If either is null, returns the other. + /// + /// Result is null if both [back] and [front] are null. + static double mergeOpacity(double back, double front) { + if (back == null) { + return front; + } else if (front == null) { + return back; + } + return (front + back) / 2.0; + } +} + +// WIP. This only handles very, very minimal use cases right now. +class DrawableText implements Drawable { + final Offset offset; + final DrawableStyle style; + final Paragraph _paragraph; + + DrawableText(String text, this.offset, this.style) + : assert(text != null && text != ''), + _paragraph = _buildParagraph(text, style); + + static Paragraph _buildParagraph(String text, DrawableStyle style) { + final ParagraphBuilder pb = new ParagraphBuilder(new ParagraphStyle()) + ..pushStyle(style.textStyle) + ..addText(text); + + return pb.build()..layout(new ParagraphConstraints(width: double.infinity)); + } + + @override + bool get hasDrawableContent => _paragraph.width > 0.0; + + @override + void draw(Canvas canvas) { + if (!hasDrawableContent) { + return; + } + canvas.drawParagraph(_paragraph, offset); + } +} + +/// Contains reusable drawing elements that can be referenced by a String ID. +class DrawableDefinitionServer { + final Map _paintServers = {}; + final Map> _clipPaths = >{}; + + /// Attempt to lookup a pre-defined [Paint] by [id]. + /// + /// [id] and [bounds] must not be null. + Paint getPaint(String id, Rect bounds) { + assert(id != null); + assert(bounds != null); + final PaintServer srv = _paintServers[id]; + + return srv != null ? srv(bounds) : null; + } + + void addPaintServer(String id, PaintServer server) { + assert(id != null); + _paintServers[id] = server; + } + + List getClipPath(String id) { + assert(id != null); + return _clipPaths[id]; + } + + void addClipPath(String id, List paths) { + assert(id != null); + _clipPaths[id] = paths; + } +} + +/// The root element of a drawable. +class DrawableRoot implements Drawable { + /// The expected coordinates used by child paths for drawing. + final Rect viewBox; + + /// The actual child or group to draw. + final List children; + + /// Contains reusable definitions such as gradients and clipPaths. + final DrawableDefinitionServer definitions; + // /// Contains [Paint]s that are used by multiple children, e.g. + // /// gradient shaders that are referenced by an identifier. + // final Map paintServers; + + /// The [DrawableStyle] for inheritence. + final DrawableStyle style; + + const DrawableRoot(this.viewBox, this.children, this.definitions, this.style); + + /// Scales the `canvas` so that the drawing units in this [Drawable] + /// will scale to the `desiredSize`. + /// + /// If the `viewBox` dimensions are not 1:1 with `desiredSize`, will scale to + /// the smaller dimension and translate to center the image along the larger + /// dimension. + void scaleCanvasToViewBox(Canvas canvas, Size desiredSize) { + final double xscale = desiredSize.width / viewBox.size.width; + final double yscale = desiredSize.height / viewBox.size.height; + + if (xscale == yscale) { + canvas.scale(xscale, yscale); + } else if (xscale < yscale) { + final double xtranslate = (viewBox.size.width - viewBox.size.height) / 2; + canvas.scale(xscale, xscale); + canvas.translate(0.0, xtranslate); + } else { + final double ytranslate = (viewBox.size.height - viewBox.size.width) / 2; + canvas.scale(yscale, yscale); + canvas.translate(ytranslate, 0.0); + } + } + + /// Clips the canvas to a rect corresponding to the `viewBox`. + void clipCanvasToViewBox(Canvas canvas) { + canvas.clipRect(viewBox.translate(viewBox.left, viewBox.top)); + } + + @override + bool get hasDrawableContent => + children.isNotEmpty == true && viewBox != null && !viewBox.isEmpty; + + @override + void draw(Canvas canvas) { + if (!hasDrawableContent) { + return; + } + for (Drawable child in children) { + child.draw(canvas); + } + } + + Picture toPicture({Size size}) { + if (viewBox == null || viewBox.size.width == 0) { + return null; + } + + final PictureRecorder recorder = new PictureRecorder(); + final Canvas canvas = new Canvas(recorder, viewBox); + canvas.save(); + if (size != null) { + scaleCanvasToViewBox(canvas, size); + } + clipCanvasToViewBox(canvas); + + draw(canvas); + canvas.restore(); + return recorder.endRecording(); + } +} + +/// Represents an element that is not rendered and has no chidlren, e.g. +/// a descriptive element. +// TODO: tie some of this into semantics/accessibility +class DrawableNoop implements Drawable { + final String name; + const DrawableNoop(this.name); + + @override + bool get hasDrawableContent => false; + + @override + void draw(Canvas canvas) {} +} + +/// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. +class DrawableGroup implements Drawable { + final List children; + final DrawableStyle style; + + const DrawableGroup(this.children, this.style); + + @override + bool get hasDrawableContent => children != null && children.isNotEmpty; + + @override + void draw(Canvas canvas) { + if (!hasDrawableContent) { + return; + } + + final Function innerDraw = () { + if (style?.transform != null) { + canvas.save(); + canvas.transform(style?.transform); + } + for (Drawable child in children) { + child.draw(canvas); + } + if (style?.transform != null) { + canvas.restore(); + } + }; + + if (style?.clipPath?.isNotEmpty == true) { + for (Path clipPath in style.clipPath) { + canvas.save(); + canvas.clipPath(clipPath); + + if (children.length > 1) { + canvas.saveLayer(clipPath.getBounds(), DrawableStyle.emptyPaint); + } + + innerDraw(); + + if (children.length > 1) { + canvas.restore(); + } + canvas.restore(); + } + } else { + innerDraw(); + } + } +} + +/// Represents a drawing element that will be rendered to the canvas. +class DrawableShape implements Drawable { + final DrawableStyle style; + final Path path; + + const DrawableShape(this.path, this.style) + : assert(path != null), + assert(style != null); + + Rect get bounds => path.getBounds(); + + // can't use bounds.isEmpty here because some paths give a 0 width or height + // see https://skia.org/user/api/SkPath_Reference#SkPath_getBounds + // can't rely on style because parent style may end up filling or stroking + // TODO: implement display properties - but that should really be done on style. + @override + bool get hasDrawableContent => bounds.width + bounds.height > 0; + + @override + void draw(Canvas canvas) { + if (!hasDrawableContent || style == null) { + return; + } + + path.fillType = style.pathFillType ?? PathFillType.nonZero; + + // if we have multiple clips to apply, need to wrap this in a loop. + final Function innerDraw = () { + if (style.fill != null && + !identical(style.fill, DrawableStyle.emptyPaint)) { + canvas.drawPath(path, style.fill); + } + + if (style.stroke != null && + !identical(style.stroke, DrawableStyle.emptyPaint)) { + if (style.dashArray != null && + !identical(style.dashArray, DrawableStyle.emptyDashArray)) { + canvas.drawPath( + dashPath(path, + dashArray: style.dashArray, dashOffset: style.dashOffset), + style.stroke); + } else { + canvas.drawPath(path, style.stroke); + } + } + }; + + if (style.clipPath?.isNotEmpty == true) { + for (Path clip in style.clipPath) { + canvas.save(); + canvas.clipPath(clip); + innerDraw(); + canvas.restore(); + } + } else { + innerDraw(); + } + } +} diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 7481aa79766d..9fd33f77e173 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -1,407 +1,22 @@ -import 'dart:typed_data'; -import 'dart:ui'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; -import 'package:path_drawing/path_drawing.dart'; -import 'package:flutter/widgets.dart' hide TextStyle; -import 'package:meta/meta.dart'; - -typedef Paint PaintServer(Rect bounds); - -/// Base interface for vector drawing. -@immutable -abstract class Drawable { - /// Whether this [Drawable] would be visible if [draw]n. - bool get isVisible; - - /// Draws the contents or children of this [Drawable] to the `canvas`, using - /// the `parentPaint` to optionally override the child's paint. - void draw(Canvas canvas); -} - -/// Styling information for vector drawing. -/// -/// Contains [Paint], [Path], dashing, transform, and text styling information. -@immutable -class DrawableStyle { - /// This should be used where 'stroke' or 'fill' are 'none'. - /// - /// This will not result in a drawing operation, but will clear out - /// inheritance. Modifying this paint should not result in any changes to - /// the image, but it should not be modified. - static final Paint emptyPaint = new Paint(); - - /// Used where 'dasharray' is 'none' - /// - /// This will not result in a drawing operation, but will clear out - /// inheritence. - static final CircularIntervalList emptyDashArray = - new CircularIntervalList(const []); - - /// If not `null` and not `identical` with [emptyPaint], will result in a stroke - /// for the rendered [DrawableShape]. Drawn __after__ the [fill]. - final Paint stroke; - - /// The dashing array to use for the [stroke], if any. - final CircularIntervalList dashArray; - - /// The [DashOffset] to use for where to begin the [dashArray]. - final DashOffset dashOffset; - - /// If not `null` and not `identical` with [emptyPaint], will result in a fill - /// for the rendered [DrawableShape]. Drawn __before__ the [stroke]. - final Paint fill; - - /// The 4x4 matrix ([Matrix4]) for a transform, if any. - final Float64List transform; - - final TextStyle textStyle; - - /// The fill rule to use for this path. - final PathFillType pathFillType; - - /// The clip to apply, if any. - final List clipPath; - - /// Controls inheriting opacity. Will be averaged with child opacity. - final double groupOpacity; - - const DrawableStyle( - {this.stroke, - this.dashArray, - this.dashOffset, - this.fill, - this.transform, - this.textStyle, - this.pathFillType, - this.groupOpacity, - this.clipPath}); - - /// Creates a new [DrawableStyle] if `parent` is not null, filling in any null properties on - /// this with the properties from other (except [groupOpacity], which is averaged). - static DrawableStyle mergeAndBlend(DrawableStyle parent, - {Paint fill, - Paint stroke, - CircularIntervalList dashArray, - DashOffset dashOffset, - Float64List transform, - TextStyle textStyle, - PathFillType pathFillType, - double groupOpacity, - List clipPath}) { - final DrawableStyle ret = new DrawableStyle( - fill: fill ?? parent?.fill, - stroke: stroke ?? parent?.stroke, - dashArray: dashArray ?? parent?.dashArray, - dashOffset: dashOffset ?? parent?.dashOffset, - // transforms aren't inherited because they're applied to canvas with save/restore - // that wraps any potential children - transform: transform, - textStyle: textStyle ?? parent?.textStyle, - pathFillType: pathFillType ?? parent?.pathFillType, - groupOpacity: mergeOpacity(groupOpacity, parent?.groupOpacity), - // clips don't make sense to inherit - applied to canvas with save/restore - // that wraps any potential children - clipPath: clipPath, - ); - - if (ret.fill != null) { - ret.fill.color = ret.fill.color.withOpacity(ret.fill.color.opacity == 1.0 - ? ret.groupOpacity ?? 1.0 - : mergeOpacity(ret.groupOpacity, ret.fill.color.opacity)); - } - if (ret.stroke != null) { - ret.stroke.color = ret.stroke.color.withOpacity( - ret.stroke.color.opacity == 1.0 - ? ret.groupOpacity ?? 1.0 - : mergeOpacity(ret.groupOpacity, ret.stroke.color.opacity)); - } - - return ret; - } - - /// Averages [back] and [front]. If either is null, returns the other. - /// - /// Result is null if both [back] and [front] are null. - static double mergeOpacity(double back, double front) { - if (back == null) { - return front; - } else if (front == null) { - return back; - } - return (front + back) / 2.0; - } -} - -// WIP -class DrawableText implements Drawable { - final Offset offset; - final DrawableStyle style; - final Paragraph _paragraph; - - DrawableText(String text, this.offset, this.style) - : assert(text != null && text != ''), - _paragraph = _buildParagraph(text, style); - - static Paragraph _buildParagraph(String text, DrawableStyle style) { - final ParagraphBuilder pb = new ParagraphBuilder(new ParagraphStyle()) - ..pushStyle(style.textStyle) - ..addText(text); - - return pb.build()..layout(new ParagraphConstraints(width: double.infinity)); - } - - @override - bool get isVisible => _paragraph.width > 0.0; - - @override - void draw(Canvas canvas) { - if (!isVisible) { - return; - } - canvas.drawParagraph(_paragraph, offset); - } -} - -/// Contains reusable drawing elements that can be referenced by a String ID. -class DrawableDefinitionServer { - final Map _paintServers = {}; - final Map> _clipPaths = >{}; - - /// Attempt to lookup a pre-defined [Paint] by [id]. - /// - /// [id] and [bounds] must not be null. - Paint getPaint(String id, Rect bounds) { - assert(id != null); - assert(bounds != null); - final PaintServer srv = _paintServers[id]; - - return srv != null ? srv(bounds) : null; - } - - void addPaintServer(String id, PaintServer server) { - assert(id != null); - _paintServers[id] = server; - } - - List getClipPath(String id) { - assert(id != null); - return _clipPaths[id]; - } - - void addClipPath(String id, List paths) { - assert(id != null); - _clipPaths[id] = paths; - } -} - -/// The root element of a drawable. -class DrawableRoot implements Drawable { - /// The expected coordinates used by child paths for drawing. - final Rect viewBox; - - /// The actual child or group to draw. - final List children; - - /// Contains reusable definitions such as gradients and clipPaths. - final DrawableDefinitionServer definitions; - // /// Contains [Paint]s that are used by multiple children, e.g. - // /// gradient shaders that are referenced by an identifier. - // final Map paintServers; - - /// The [DrawableStyle] for inheritence. - final DrawableStyle style; - - const DrawableRoot(this.viewBox, this.children, this.definitions, this.style); - - /// Scales the `canvas` so that the drawing units in this [Drawable] - /// will scale to the `desiredSize`. - /// - /// If the `viewBox` dimensions are not 1:1 with `desiredSize`, will scale to - /// the smaller dimension and translate to center the image along the larger - /// dimension. - void scaleCanvasToViewBox(Canvas canvas, Size desiredSize) { - final double xscale = desiredSize.width / viewBox.size.width; - final double yscale = desiredSize.height / viewBox.size.height; - - if (xscale == yscale) { - canvas.scale(xscale, yscale); - } else if (xscale < yscale) { - final double xtranslate = (viewBox.size.width - viewBox.size.height) / 2; - canvas.scale(xscale, xscale); - canvas.translate(0.0, xtranslate); - } else { - final double ytranslate = (viewBox.size.height - viewBox.size.width) / 2; - canvas.scale(yscale, yscale); - canvas.translate(ytranslate, 0.0); - } - } - - /// Clips the canvas to a rect corresponding to the `viewBox`. - void clipCanvasToViewBox(Canvas canvas) { - canvas.clipRect(viewBox.translate(viewBox.left, viewBox.top)); - } - - @override - bool get isVisible => - children.isNotEmpty == true && viewBox != null && !viewBox.isEmpty; - - @override - void draw(Canvas canvas) { - if (!isVisible) { - return; - } - for (Drawable child in children) { - child.draw(canvas); - } - } -} - -/// Represents an element that is not rendered and has no chidlren, e.g. -/// a descriptive element. -// TODO: tie some of this into semantics/accessibility -class DrawableNoop implements Drawable { - final String name; - const DrawableNoop(this.name); - - @override - bool get isVisible => false; - - @override - void draw(Canvas canvas) {} -} - -/// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. -class DrawableGroup implements Drawable { - final List children; - final DrawableStyle style; - - const DrawableGroup(this.children, this.style); - - @override - bool get isVisible => children != null && children.isNotEmpty; - - @override - void draw(Canvas canvas) { - if (!isVisible) { - return; - } - - final Function innerDraw = () { - if (style?.transform != null) { - canvas.save(); - canvas.transform(style?.transform); - } - for (Drawable child in children) { - child.draw(canvas); - } - if (style?.transform != null) { - canvas.restore(); - } - }; - - if (style?.clipPath?.isNotEmpty == true) { - for (Path clipPath in style.clipPath) { - canvas.save(); - canvas.clipPath(clipPath); - - if (children.length > 1) { - canvas.saveLayer(clipPath.getBounds(), DrawableStyle.emptyPaint); - } - - innerDraw(); - - if (children.length > 1) { - canvas.restore(); - } - canvas.restore(); - } - } else { - innerDraw(); - } - } -} - -/// Represents a drawing element that will be rendered to the canvas. -class DrawableShape implements Drawable { - final DrawableStyle style; - final Path path; - - const DrawableShape(this.path, this.style) : assert(path != null); - - Rect get bounds => path?.getBounds(); - - // can't use bounds.isEmpty here because some paths give a 0 width or height - // see https://skia.org/user/api/SkPath_Reference#SkPath_getBounds - // can't rely on style because parent style may end up filling or stroking - // TODO: implement display properties - @override - bool get isVisible => bounds.width + bounds.height > 0; - - @override - void draw(Canvas canvas) { - if (!isVisible) { - return; - } - - path.fillType = style.pathFillType ?? PathFillType.nonZero; - - // if we have multiple clips to apply, need to wrap this in a loop. - final Function innerDraw = () { - if (style?.fill != null && - !identical(style.fill, DrawableStyle.emptyPaint)) { - canvas.drawPath(path, style.fill); - } - - if (style?.stroke != null && - !identical(style.stroke, DrawableStyle.emptyPaint)) { - if (style.dashArray != null && - !identical(style.dashArray, DrawableStyle.emptyDashArray)) { - canvas.drawPath( - dashPath(path, - dashArray: style.dashArray, dashOffset: style.dashOffset), - style.stroke); - } else { - canvas.drawPath(path, style.stroke); - } - } - }; - - if (style?.clipPath?.isNotEmpty == true) { - for (Path clip in style.clipPath) { - canvas.save(); - canvas.clipPath(clip); - innerDraw(); - canvas.restore(); - } - } else { - innerDraw(); - } - } -} +import 'vector_drawable.dart'; /// A [CustomPainter] that can render a [DrawableRoot] to a [Canvas]. class VectorPainter extends CustomPainter { final DrawableRoot drawable; - final bool _clipToViewBox; - VectorPainter(this.drawable, {bool clipToViewBox = true}) - : _clipToViewBox = clipToViewBox; + VectorPainter(this.drawable); @override void paint(Canvas canvas, Size size) { - Rect p; - p.hashCode; - if (drawable == null || - drawable.viewBox == null || - drawable.viewBox.size.width == 0) { + if (drawable == null) { return; } drawable.scaleCanvasToViewBox(canvas, size); - if (_clipToViewBox) { - drawable.clipCanvasToViewBox(canvas); - } - + drawable.clipCanvasToViewBox(canvas); drawable.draw(canvas); } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index afc8e9fd8f68..a9843de015db 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -2,49 +2,57 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart' show rootBundle, AssetBundle; import 'package:flutter/widgets.dart'; import 'package:xml/xml.dart' hide parse; import 'package:xml/xml.dart' as xml show parse; +import 'src/picture_provider.dart'; +import 'src/picture_stream.dart'; +import 'src/render_picture.dart'; import 'src/svg/xml_parsers.dart'; import 'src/svg_parser.dart'; -import 'src/vector_painter.dart'; +import 'src/vector_drawable.dart'; import 'vector_drawable.dart'; /// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. class SvgImage extends VectorDrawableImage { const SvgImage._(Future future, Size size, - {bool clipToViewBox, - Key key, + {Key key, Widget child, PaintLocation paintLocation, ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) + WidgetBuilder loadingPlaceholderBuilder, + Color color, + BlendMode colorBlendMode}) : super(future, size, - clipToViewBox: clipToViewBox, child: child, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, - loadingPlaceholderBuilder: loadingPlaceholderBuilder); + loadingPlaceholderBuilder: loadingPlaceholderBuilder, + color: color, + colorBlendMode: colorBlendMode); factory SvgImage.fromString(String svg, Size size, {Key key, - bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, Widget child, ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) { + WidgetBuilder loadingPlaceholderBuilder, + Color color, + BlendMode colorBlendMode}) { return new SvgImage._( - new Future.value(fromSvgString(svg, size)), + new Future.value(fromSvgString(svg)), size, - clipToViewBox: clipToViewBox, child: child, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, loadingPlaceholderBuilder: loadingPlaceholderBuilder, + color: color, + colorBlendMode: colorBlendMode, ); } @@ -53,20 +61,22 @@ class SvgImage extends VectorDrawableImage { {Key key, AssetBundle bundle, String package, - bool clipToViewBox = true, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, Widget child, ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) { + WidgetBuilder loadingPlaceholderBuilder, + Color color, + BlendMode colorBlendMode}) { return new SvgImage._( - loadAsset(assetName, size, bundle: bundle, package: package), + loadAsset(assetName, bundle: bundle, package: package), size, - clipToViewBox: clipToViewBox, child: child, key: key, paintLocation: paintLocation, errorWidgetBuilder: errorWidgetBuilder, loadingPlaceholderBuilder: loadingPlaceholderBuilder, + color: color, + colorBlendMode: colorBlendMode, ); } @@ -74,15 +84,16 @@ class SvgImage extends VectorDrawableImage { factory SvgImage.network(String uri, Size size, {Map headers, Key key, - bool clipToViewBox = true, Widget child, - PaintLocation paintLocation = PaintLocation.Background, + PaintLocation paintLocation = PaintLocation.background, ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) { + WidgetBuilder loadingPlaceholderBuilder, + Color color, + BlendMode colorBlendMode}) { return new SvgImage._( - loadNetworkAsset(uri, size), + loadNetworkAsset(uri, + colorFilter: ColorFilter.mode(color, colorBlendMode)), size, - clipToViewBox: clipToViewBox, child: child, key: key, paintLocation: paintLocation, @@ -92,9 +103,8 @@ class SvgImage extends VectorDrawableImage { } } -/// Creates a [DrawableRoot] from a string of SVG data. [size] specifies the -/// size of the coordinate space to draw to. -DrawableRoot fromSvgString(String rawSvg, Size size) { +/// Creates a [DrawableRoot] from a string of SVG data. +DrawableRoot fromSvgString(String rawSvg) { final XmlElement svg = xml.parse(rawSvg).rootElement; final Rect viewBox = parseViewBox(svg); //final Map paintServers = {}; @@ -107,10 +117,7 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { (XmlNode child) => parseSvgElement( child, definitions, - new Rect.fromPoints( - Offset.zero, - new Offset(size.width, size.height), - ), + viewBox, style, ), ) @@ -123,22 +130,21 @@ DrawableRoot fromSvgString(String rawSvg, Size size) { ); } -/// Creates a [DrawableRoot] from a bundled asset. [size] specifies the size -/// of the coordinate space to draw to. -Future loadAsset(String assetName, Size size, +/// Creates a [DrawableRoot] from a bundled asset. +Future loadAsset(String assetName, {AssetBundle bundle, String package}) async { bundle ??= rootBundle; final String rawSvg = await bundle.loadString( package == null ? assetName : 'packages/$package/$assetName', ); - return fromSvgString(rawSvg, size); + return fromSvgString(rawSvg); } final HttpClient _httpClient = new HttpClient(); /// Creates a [DrawableRoot] from a network asset with an HTTP get request. -/// [size] specifies the size of the coordinate space to draw to. -Future loadNetworkAsset(String url, Size size) async { +Future loadNetworkAsset(String url, + {ColorFilter colorFilter}) async { final Uri uri = Uri.base.resolve(url); final HttpClientRequest request = await _httpClient.getUrl(uri); final HttpClientResponse response = await request.close(); @@ -148,7 +154,7 @@ Future loadNetworkAsset(String url, Size size) async { } final String rawSvg = await _consolidateHttpClientResponse(response); - return fromSvgString(rawSvg, size); + return fromSvgString(rawSvg); } Future _consolidateHttpClientResponse( @@ -164,3 +170,122 @@ Future _consolidateHttpClientResponse( return completer.future; } + +class SvgPicture extends StatefulWidget { + const SvgPicture(this.pictureProvider, this.width, this.height, + {this.matchTextDirection = false}); + + final PictureProvider pictureProvider; + final double width; + final double height; + final bool matchTextDirection; + + @override + State createState() => new _SvgPictureState(); +} + +class _SvgPictureState extends State { + PictureInfo _picture; + PictureStream _pictureStream; + bool _isListeningToStream = false; + + @override + void didChangeDependencies() { + _resolveImage(); + + if (TickerMode.of(context)) + _listenToStream(); + else + _stopListeningToStream(); + + super.didChangeDependencies(); + } + + @override + void didUpdateWidget(SvgPicture oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.pictureProvider != oldWidget.pictureProvider) { + _resolveImage(); + } + } + + @override + void reassemble() { + _resolveImage(); // in case the image cache was flushed + super.reassemble(); + } + + void _resolveImage() { + final PictureStream newStream = widget.pictureProvider.resolve(null); + assert(newStream != null); + _updateSourceStream(newStream); + } + + void _handleImageChanged(PictureInfo imageInfo, bool synchronousCall) { + setState(() { + _picture = imageInfo; + }); + } + + // Update _pictureStream to newStream, and moves the stream listener + // registration from the old stream to the new stream (if a listener was + // registered). + void _updateSourceStream(PictureStream newStream) { + if (_pictureStream?.key == newStream?.key) { + return; + } + + if (_isListeningToStream) + _pictureStream.removeListener(_handleImageChanged); + + // if (!widget.gaplessPlayback) + // setState(() { + // _imageInfo = null; + // }); + + _pictureStream = newStream; + if (_isListeningToStream) { + _pictureStream.addListener(_handleImageChanged); + } + } + + void _listenToStream() { + if (_isListeningToStream) { + return; + } + _pictureStream.addListener(_handleImageChanged); + _isListeningToStream = true; + } + + void _stopListeningToStream() { + if (!_isListeningToStream) { + return; + } + _pictureStream.removeListener(_handleImageChanged); + _isListeningToStream = false; + } + + @override + void dispose() { + assert(_pictureStream != null); + _stopListeningToStream(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return new RawPicture( + _picture, + width: widget.width, + height: widget.height, + matchTextDirection: widget.matchTextDirection, + ); + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder description) { + super.debugFillProperties(description); + description + .add(new DiagnosticsProperty('stream', _pictureStream)); + } +} diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart index a9dbdd642e11..a35532e4d4ea 100644 --- a/third_party/lib/vector_drawable.dart +++ b/third_party/lib/vector_drawable.dart @@ -3,15 +3,14 @@ import 'dart:ui'; import 'package:flutter/widgets.dart'; +import 'src/vector_drawable.dart'; import 'src/vector_painter.dart'; -enum PaintLocation { Foreground, Background } +enum PaintLocation { foreground, background } /// Handles rendering the [DrawableRoot] from `future` to a [Canvas]. /// -/// To control the coordinate space, use the `size` parameter. In most -/// contexts, you should prefer keeping `clipToViewBox` as true to avoid -/// potentially drawing outside the bounds of the canvas. By default, +/// To control the coordinate space, use the `size` parameter. By default, /// this will draw to the background (meaning the child widget will be /// rendered after drawing). You can change that by specifying /// `PaintLocation.Foreground`. @@ -32,10 +31,6 @@ class VectorDrawableImage extends StatelessWidget { /// The [Future] that resolves the drawing content. final Future future; - /// Whether to allow drawing outside of the canvas or not. Defaults to - /// true. - final bool clipToViewBox; - /// Whether to draw before or after child content. Defaults to background /// (before). final PaintLocation paintLocation; @@ -49,13 +44,18 @@ class VectorDrawableImage extends StatelessWidget { /// Child content for this widget. final Widget child; + final Color color; + + final BlendMode colorBlendMode; + const VectorDrawableImage(this.future, this.size, - {this.clipToViewBox = true, - Key key, - this.paintLocation = PaintLocation.Background, + {Key key, + this.paintLocation = PaintLocation.background, this.errorWidgetBuilder, this.loadingPlaceholderBuilder, - this.child}) + this.child, + this.color, + this.colorBlendMode = BlendMode.src}) : super(key: key); @override @@ -76,13 +76,13 @@ class VectorDrawableImage extends StatelessWidget { )); } else if (snapShot.hasData) { final CustomPainter painter = - new VectorPainter(snapShot.data, clipToViewBox: clipToViewBox); + new VectorPainter(snapShot.data); return new RepaintBoundary.wrap( CustomPaint( - painter: paintLocation == PaintLocation.Background + painter: paintLocation == PaintLocation.background ? painter : null, - foregroundPainter: paintLocation == PaintLocation.Foreground + foregroundPainter: paintLocation == PaintLocation.foreground ? painter : null, size: size, @@ -98,3 +98,4 @@ class VectorDrawableImage extends StatelessWidget { ); } } + diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 33b2cd00a71b..c8d3fe2eed2b 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -98,7 +98,7 @@ void main() { test('loadNetworkAsset HTTP exception', () { HttpOverrides.runZoned(() { when(mockResponse.statusCode).thenReturn(400); - expect(() => loadNetworkAsset('test.svg', const Size(100.0, 100.0)), + expect(() => loadNetworkAsset('test.svg'), throwsA(const isInstanceOf())); }, createHttpClient: (SecurityContext c) => mockHttpClient); }); diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index 7f41bade4409..b77e7f1666fd 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -13,7 +13,7 @@ import 'dart:ui'; import 'package:path/path.dart' as path; import 'package:flutter_svg/svg.dart' as svg; -import 'package:flutter_svg/src/vector_painter.dart'; +import 'package:flutter_svg/src/vector_drawable.dart'; Future getSvgPngBytes(String svgData) async { final PictureRecorder rec = new PictureRecorder(); @@ -21,7 +21,7 @@ Future getSvgPngBytes(String svgData) async { const Size size = const Size(200.0, 200.0); - final DrawableRoot svgRoot = svg.fromSvgString(svgData, size); + final DrawableRoot svgRoot = svg.fromSvgString(svgData); svgRoot.scaleCanvasToViewBox(canvas, size); svgRoot.clipCanvasToViewBox(canvas); From e3bc3d67cdf58af8be79c7de8345c6bd139c036f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 25 May 2018 09:11:01 -0400 Subject: [PATCH 080/512] more refactoring, getting closer, deprecate old classes --- third_party/example/main.dart | 24 ++--- third_party/lib/flutter_svg.dart | 3 +- third_party/lib/src/picture_provider.dart | 120 +++++++++++++--------- third_party/lib/src/vector_painter.dart | 1 + third_party/lib/svg.dart | 54 +++++++++- third_party/lib/vector_drawable.dart | 2 + 6 files changed, 133 insertions(+), 71 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 0197d7f139b6..de03997bc501 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:flutter/material.dart'; import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -88,28 +90,18 @@ class _MyHomePageState extends State { for (String assetName in assetNames) { _painters.add( - // new FractionallySizedBox( - //size: new Size.square(_dimension), - // child: - new SvgPicture(new ExactAssetPicture(assetName), _dimension, _dimension), - // ), - - // _painters.add(new SvgImage.asset( - // assetName, - // new Size(_dimension, _dimension), - // errorWidgetBuilder: customErrorBuilder, - // ), + new SvgPicture.asset(assetName, _dimension, _dimension), ); } for (String uriName in uriNames) { _painters.add( - new SvgImage.network( + new SvgPicture.network( uriName, - new Size(_dimension, _dimension), - loadingPlaceholderBuilder: (BuildContext context) => new Container( - padding: const EdgeInsets.all(30.0), - child: const CircularProgressIndicator()), + _dimension, _dimension, + // loadingPlaceholderBuilder: (BuildContext context) => new Container( + // padding: const EdgeInsets.all(30.0), + // child: const CircularProgressIndicator()), ), ); } diff --git a/third_party/lib/flutter_svg.dart b/third_party/lib/flutter_svg.dart index 3ed03a6b2508..f1171ffa986e 100644 --- a/third_party/lib/flutter_svg.dart +++ b/third_party/lib/flutter_svg.dart @@ -1,3 +1,4 @@ +export 'src/picture_provider.dart'; +export 'src/picture_stream.dart'; export 'src/vector_drawable.dart'; export 'svg.dart'; -export 'vector_drawable.dart'; diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index ec84d2792bfe..374e0da7f5eb 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -5,15 +5,17 @@ import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; -import 'dart:ui' show Picture, Size, Locale, TextDirection, hashValues; +import 'dart:ui' show Rect, Locale, TextDirection, hashValues; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; // TODO: make this less SVG specific -import '../svg.dart'; +// import '../svg.dart'; import 'picture_stream.dart'; -import 'vector_drawable.dart'; +// import 'vector_drawable.dart'; + +typedef FutureOr PictureInfoDecoder(Uint8List data); /// Configuration information passed to the [ImageProvider.resolve] method to /// select a specific image. @@ -25,17 +27,17 @@ import 'vector_drawable.dart'; /// * [ImageProvider], which uses [ImageConfiguration] objects to determine /// which image to obtain. @immutable -class ImageConfiguration { +class PictureConfiguration { /// Creates an object holding the configuration information for an [ImageProvider]. /// /// All the arguments are optional. Configuration information is merely /// advisory and best-effort. - const ImageConfiguration({ + const PictureConfiguration({ this.bundle, this.devicePixelRatio, this.locale, this.textDirection, - this.size, + this.viewBox, this.platform, }); @@ -43,20 +45,20 @@ class ImageConfiguration { /// /// All the arguments are optional. Configuration information is merely /// advisory and best-effort. - ImageConfiguration copyWith({ + PictureConfiguration copyWith({ AssetBundle bundle, double devicePixelRatio, Locale locale, TextDirection textDirection, - Size size, + Rect viewBox, String platform, }) { - return new ImageConfiguration( + return new PictureConfiguration( bundle: bundle ?? this.bundle, devicePixelRatio: devicePixelRatio ?? this.devicePixelRatio, locale: locale ?? this.locale, textDirection: textDirection ?? this.textDirection, - size: size ?? this.size, + viewBox: viewBox ?? this.viewBox, platform: platform ?? this.platform, ); } @@ -75,7 +77,7 @@ class ImageConfiguration { final TextDirection textDirection; /// The size at which the image will be rendered. - final Size size; + final Rect viewBox; /// The [TargetPlatform] for which assets should be used. This allows images /// to be specified in a platform-neutral fashion yet use different assets on @@ -86,25 +88,25 @@ class ImageConfiguration { /// An image configuration that provides no additional information. /// /// Useful when resolving an [ImageProvider] without any context. - static const ImageConfiguration empty = const ImageConfiguration(); + static const PictureConfiguration empty = const PictureConfiguration(); @override bool operator ==(dynamic other) { if (other.runtimeType != runtimeType) { return false; } - final ImageConfiguration typedOther = other; + final PictureConfiguration typedOther = other; return typedOther.bundle == bundle && typedOther.devicePixelRatio == devicePixelRatio && typedOther.locale == locale && typedOther.textDirection == textDirection && - typedOther.size == size && + typedOther.viewBox == viewBox && typedOther.platform == platform; } @override int get hashCode => - hashValues(bundle, devicePixelRatio, locale, size, platform); + hashValues(bundle, devicePixelRatio, locale, viewBox, platform); @override String toString() { @@ -139,11 +141,11 @@ class ImageConfiguration { result.write('textDirection: $textDirection'); hasArguments = true; } - if (size != null) { + if (viewBox != null) { if (hasArguments) { result.write(', '); } - result.write('size: $size'); + result.write('viewBox: $viewBox'); hasArguments = true; } if (platform != null) { @@ -265,7 +267,7 @@ abstract class PictureProvider { /// /// Subclasses should implement [obtainKey] and [load], which are used by this /// method. - PictureStream resolve(PictureInfo picture) { + PictureStream resolve(PictureConfiguration picture) { // assert(picture != null); final PictureStream stream = new PictureStream(); T obtainedKey; @@ -358,13 +360,15 @@ abstract class AssetBundlePictureProvider extends PictureProvider { /// Abstract const constructor. This constructor enables subclasses to provide /// const constructors so that they can be used in const expressions. - const AssetBundlePictureProvider(); + const AssetBundlePictureProvider(this.decoder) : assert(decoder != null); + + final PictureInfoDecoder decoder; /// Converts a key into an [PictureStreamCompleter], and begins fetching the - /// image using [loadAsync]. + /// image using [_loadAsync]. @override PictureStreamCompleter load(AssetBundlePictureKey key) { - return new OneFramePictureStreamCompleter(loadAsync(key), + return new OneFramePictureStreamCompleter(_loadAsync(key), informationCollector: (StringBuffer information) { information.writeln('Image provider: $this'); information.write('Image key: $key'); @@ -376,16 +380,18 @@ abstract class AssetBundlePictureProvider /// /// This function is used by [load]. @protected - Future loadAsync(AssetBundlePictureKey key) async { - final String data = await key.bundle.loadString(key.name); + Future _loadAsync(AssetBundlePictureKey key) async { + final ByteData data = await key.bundle.load(key.name); if (data == null) { throw 'Unable to read data'; } - final DrawableRoot root = fromSvgString(data); - return new PictureInfo(picture: root.toPicture(), viewBox: root.viewBox); + + return decoder(data.buffer.asUint8List()); } } +final HttpClient _httpClient = new HttpClient(); + /// Fetches the given URL from the network, associating it with the given scale. /// /// The image will be cached regardless of cache headers from the server. @@ -400,7 +406,10 @@ class NetworkPicture extends PictureProvider { /// Creates an object that fetches the image at the given URL. /// /// The arguments must not be null. - const NetworkPicture(this.url, {this.headers}) : assert(url != null); + const NetworkPicture(this.decoder, this.url, {this.headers}) + : assert(url != null); + + final PictureInfoDecoder decoder; /// The URL from which the image will be fetched. final String url; @@ -415,18 +424,25 @@ class NetworkPicture extends PictureProvider { @override PictureStreamCompleter load(NetworkPicture key) { - return new OneFramePictureStreamCompleter(loadAsync(key), + return new OneFramePictureStreamCompleter(_loadAsync(key), informationCollector: (StringBuffer information) { information.writeln('Image provider: $this'); information.write('Image key: $key'); }); } - Future loadAsync(NetworkPicture key) async { + Future _loadAsync(NetworkPicture key) async { assert(key == this); - final DrawableRoot root = await loadNetworkAsset(key.url); + final Uri uri = Uri.base.resolve(url); + final HttpClientRequest request = await _httpClient.getUrl(uri); + final HttpClientResponse response = await request.close(); - return new PictureInfo(picture: root.toPicture(), viewBox: root.viewBox); + if (response.statusCode != HttpStatus.OK) { + throw new HttpException('Could not get network asset', uri: uri); + } + final Uint8List bytes = await consolidateHttpClientResponseBytes(response); + + return decoder(bytes); } @override @@ -451,38 +467,41 @@ class NetworkPicture extends PictureProvider { /// See also: /// /// * [Image.file] for a shorthand of an [Image] widget backed by [FileImage]. -class FileImage extends PictureProvider { +class FilePicture extends PictureProvider { /// Creates an object that decodes a [File] as an image. /// /// The arguments must not be null. - const FileImage(this.file) : assert(file != null); + const FilePicture(this.decoder, this.file) + : assert(decoder != null), + assert(file != null); /// The file to decode into an image. final File file; + final PictureInfoDecoder decoder; + @override - Future obtainKey() { - return new SynchronousFuture(this); + Future obtainKey() { + return new SynchronousFuture(this); } @override - PictureStreamCompleter load(FileImage key) { - return new OneFramePictureStreamCompleter(loadAsync(key), + PictureStreamCompleter load(FilePicture key) { + return new OneFramePictureStreamCompleter(_loadAsync(key), informationCollector: (StringBuffer information) { information.writeln('Path: ${file?.path}'); }); } - Future loadAsync(FileImage key) async { + Future _loadAsync(FilePicture key) async { assert(key == this); - final String data = await file.readAsString(); + final Uint8List data = await file.readAsBytes(); if (data == null || data.isEmpty) { return null; } - final DrawableRoot root = fromSvgString(data); - return new PictureInfo(picture: root.toPicture(), viewBox: root.viewBox); + return decoder(data); } @override @@ -490,7 +509,7 @@ class FileImage extends PictureProvider { if (other.runtimeType != runtimeType) { return false; } - final FileImage typedOther = other; + final FilePicture typedOther = other; return file?.path == typedOther.file?.path; } @@ -517,10 +536,12 @@ class MemoryPicture extends PictureProvider { /// Creates an object that decodes a [Uint8List] buffer as an image. /// /// The arguments must not be null. - const MemoryPicture(this.bytes) : assert(bytes != null); + const MemoryPicture(this.decoder, this.bytes) : assert(bytes != null); + + final PictureInfoDecoder decoder; /// The bytes to decode into an image. - final String bytes; + final Uint8List bytes; @override Future obtainKey() { @@ -529,15 +550,12 @@ class MemoryPicture extends PictureProvider { @override PictureStreamCompleter load(MemoryPicture key) { - return new OneFramePictureStreamCompleter(loadAsync(key)); + return new OneFramePictureStreamCompleter(_loadAsync(key)); } - Future loadAsync(MemoryPicture key) { + Future _loadAsync(MemoryPicture key) { assert(key == this); - final DrawableRoot root = fromSvgString(bytes); - return Future.value( - new PictureInfo(picture: root.toPicture(), viewBox: root.viewBox), - ); + return decoder(bytes); } @override @@ -638,10 +656,12 @@ class ExactAssetPicture extends AssetBundlePictureProvider { /// included in a package. See the documentation for the [ExactAssetImage] class /// itself for details. const ExactAssetPicture( + PictureInfoDecoder decoder, this.assetName, { this.bundle, this.package, - }) : assert(assetName != null); + }) : assert(assetName != null), + super(decoder); /// The name of the asset. final String assetName; diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 9fd33f77e173..2926d0129d7b 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -4,6 +4,7 @@ import 'package:flutter/widgets.dart'; import 'vector_drawable.dart'; /// A [CustomPainter] that can render a [DrawableRoot] to a [Canvas]. +@deprecated class VectorPainter extends CustomPainter { final DrawableRoot drawable; diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index a9843de015db..e30d3889cba2 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'dart:typed_data'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart' show rootBundle, AssetBundle; @@ -16,6 +17,8 @@ import 'src/svg_parser.dart'; import 'src/vector_drawable.dart'; import 'vector_drawable.dart'; +@deprecated + /// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. class SvgImage extends VectorDrawableImage { const SvgImage._(Future future, Size size, @@ -103,6 +106,15 @@ class SvgImage extends VectorDrawableImage { } } +PictureInfo svgPictureDecoder(Uint8List raw) { + final DrawableRoot svg = fromSvgBytes(raw); + return new PictureInfo(picture: svg.toPicture(), viewBox: svg.viewBox); +} + +DrawableRoot fromSvgBytes(Uint8List raw) { + return fromSvgString(utf8.decode(raw)); +} + /// Creates a [DrawableRoot] from a string of SVG data. DrawableRoot fromSvgString(String rawSvg) { final XmlElement svg = xml.parse(rawSvg).rootElement; @@ -131,6 +143,7 @@ DrawableRoot fromSvgString(String rawSvg) { } /// Creates a [DrawableRoot] from a bundled asset. +@deprecated Future loadAsset(String assetName, {AssetBundle bundle, String package}) async { bundle ??= rootBundle; @@ -140,9 +153,11 @@ Future loadAsset(String assetName, return fromSvgString(rawSvg); } +@deprecated final HttpClient _httpClient = new HttpClient(); /// Creates a [DrawableRoot] from a network asset with an HTTP get request. +@deprecated Future loadNetworkAsset(String url, {ColorFilter colorFilter}) async { final Uri uri = Uri.base.resolve(url); @@ -157,6 +172,7 @@ Future loadNetworkAsset(String url, return fromSvgString(rawSvg); } +@deprecated Future _consolidateHttpClientResponse( HttpClientResponse response) async { final Completer completer = new Completer.sync(); @@ -171,9 +187,39 @@ Future _consolidateHttpClientResponse( return completer.future; } +Image icon; + class SvgPicture extends StatefulWidget { const SvgPicture(this.pictureProvider, this.width, this.height, - {this.matchTextDirection = false}); + {Key key, this.matchTextDirection = false}) + : super(key: key); + + SvgPicture.asset(String assetName, this.width, this.height, + {Key key, + this.matchTextDirection = false, + AssetBundle bundle, + String package}) + : pictureProvider = new ExactAssetPicture(svgDecoder, assetName, + bundle: bundle, package: package), + super(key: key); + + SvgPicture.network(String url, this.width, this.height, + {Key key, Map headers, this.matchTextDirection = false}) + : pictureProvider = new NetworkPicture(svgDecoder, url, headers: headers), + super(key: key); + + SvgPicture.file(File file, this.width, this.height, + {Key key, this.matchTextDirection = false}) + : pictureProvider = new FilePicture(svgDecoder, file), + super(key: key); + + SvgPicture.memory(Uint8List bytes, this.width, this.height, + {Key key, this.matchTextDirection = false}) + : pictureProvider = new MemoryPicture(svgDecoder, bytes), + super(key: key); + + static final PictureInfoDecoder svgDecoder = + (Uint8List bytes) => svgPictureDecoder(bytes); final PictureProvider pictureProvider; final double width; @@ -193,11 +239,11 @@ class _SvgPictureState extends State { void didChangeDependencies() { _resolveImage(); - if (TickerMode.of(context)) + if (TickerMode.of(context)) { _listenToStream(); - else + } else { _stopListeningToStream(); - + } super.didChangeDependencies(); } diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart index a35532e4d4ea..7320d88d3e0b 100644 --- a/third_party/lib/vector_drawable.dart +++ b/third_party/lib/vector_drawable.dart @@ -6,6 +6,7 @@ import 'package:flutter/widgets.dart'; import 'src/vector_drawable.dart'; import 'src/vector_painter.dart'; +@deprecated enum PaintLocation { foreground, background } /// Handles rendering the [DrawableRoot] from `future` to a [Canvas]. @@ -21,6 +22,7 @@ enum PaintLocation { foreground, background } /// /// By default, an [ErrorWidget] will be rendered if an error occurs. This /// can be replace with a custom [ErrorWidgetBuilder] to taste. +@deprecated class VectorDrawableImage extends StatelessWidget { static final WidgetBuilder defaultPlaceholderBuilder = (BuildContext ctx) => const LimitedBox(); From 0ab3f45a009eb0d40b9a5b157b703cdffc51e076 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 25 May 2018 11:34:14 -0400 Subject: [PATCH 081/512] update tests, add String version --- third_party/example/main.dart | 3 - third_party/lib/avd.dart | 1 + third_party/lib/src/picture_provider.dart | 97 ++++++++++++++++------- third_party/lib/src/picture_stream.dart | 44 +++++----- third_party/lib/svg.dart | 34 +++++--- third_party/lib/vector_drawable.dart | 4 +- third_party/test/widget_svg_test.dart | 58 ++++++++------ 7 files changed, 151 insertions(+), 90 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index de03997bc501..349a0b6d140e 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -1,9 +1,6 @@ -import 'dart:typed_data'; - import 'package:flutter/material.dart'; import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_svg/src/picture_provider.dart'; const List assetNames = const [ // 'assets/notfound.svg', diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 41c22733784c..58d6f20aef4f 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -1,3 +1,4 @@ +// ignore_for_file: deprecated_member_use import 'dart:async'; import 'dart:convert'; import 'dart:io'; diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 374e0da7f5eb..459e8dddbbdf 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -15,7 +15,8 @@ import 'package:flutter/services.dart'; import 'picture_stream.dart'; // import 'vector_drawable.dart'; -typedef FutureOr PictureInfoDecoder(Uint8List data); +typedef FutureOr PictureInfoDecoder(T data); + /// Configuration information passed to the [ImageProvider.resolve] method to /// select a specific image. @@ -85,7 +86,7 @@ class PictureConfiguration { /// shadows. final TargetPlatform platform; - /// An image configuration that provides no additional information. + /// a picture configuration that provides no additional information. /// /// Useful when resolving an [ImageProvider] without any context. static const PictureConfiguration empty = const PictureConfiguration(); @@ -160,7 +161,7 @@ class PictureConfiguration { } } -/// Identifies an image without committing to the precise final asset. This +/// Identifies a picture without committing to the precise final asset. This /// allows a set of images to be identified and for the precise image to later /// be resolved based on the environment, e.g. the device pixel ratio. /// @@ -281,7 +282,7 @@ abstract class PictureProvider { exception: exception, stack: stack, library: 'services library', - context: 'while resolving an image', + context: 'while resolving a picture', silent: true, // could be a network error or whatnot informationCollector: (StringBuffer information) { information.writeln('Image provider: $this'); @@ -293,7 +294,7 @@ abstract class PictureProvider { return stream; } - /// Converts an ImageProvider's settings plus an ImageConfiguration to a key + /// Converts a pictureProvider's settings plus a pictureConfiguration to a key /// that describes the precise image to load. /// /// The type of the key is determined by the subclass. It is a value that @@ -362,7 +363,7 @@ abstract class AssetBundlePictureProvider /// const constructors so that they can be used in const expressions. const AssetBundlePictureProvider(this.decoder) : assert(decoder != null); - final PictureInfoDecoder decoder; + final PictureInfoDecoder decoder; /// Converts a key into an [PictureStreamCompleter], and begins fetching the /// image using [_loadAsync]. @@ -386,7 +387,7 @@ abstract class AssetBundlePictureProvider throw 'Unable to read data'; } - return decoder(data.buffer.asUint8List()); + return await decoder(data.buffer.asUint8List()); } } @@ -400,7 +401,7 @@ final HttpClient _httpClient = new HttpClient(); /// /// * [Image.network] for a shorthand of an [Image] widget backed by [NetworkImage]. // TODO(ianh): Find some way to honour cache headers to the extent that when the -// last reference to an image is released, we proactively evict the image from +// last reference to a picture is released, we proactively evict the image from // our cache if the headers describe the image as having expired at that point. class NetworkPicture extends PictureProvider { /// Creates an object that fetches the image at the given URL. @@ -409,7 +410,7 @@ class NetworkPicture extends PictureProvider { const NetworkPicture(this.decoder, this.url, {this.headers}) : assert(url != null); - final PictureInfoDecoder decoder; + final PictureInfoDecoder decoder; /// The URL from which the image will be fetched. final String url; @@ -442,7 +443,7 @@ class NetworkPicture extends PictureProvider { } final Uint8List bytes = await consolidateHttpClientResponseBytes(response); - return decoder(bytes); + return await decoder(bytes); } @override @@ -461,24 +462,24 @@ class NetworkPicture extends PictureProvider { String toString() => '$runtimeType("$url", $headers)'; } -/// Decodes the given [File] object as an image, associating it with the given +/// Decodes the given [File] object as a picture, associating it with the given /// scale. /// /// See also: /// /// * [Image.file] for a shorthand of an [Image] widget backed by [FileImage]. class FilePicture extends PictureProvider { - /// Creates an object that decodes a [File] as an image. + /// Creates an object that decodes a [File] as a picture. /// /// The arguments must not be null. const FilePicture(this.decoder, this.file) : assert(decoder != null), assert(file != null); - /// The file to decode into an image. + /// The file to decode into a picture. final File file; - final PictureInfoDecoder decoder; + final PictureInfoDecoder decoder; @override Future obtainKey() { @@ -501,7 +502,7 @@ class FilePicture extends PictureProvider { return null; } - return decoder(data); + return await decoder(data); } @override @@ -520,27 +521,27 @@ class FilePicture extends PictureProvider { String toString() => '$runtimeType("${file?.path}")'; } -/// Decodes the given [String] buffer as an image, associating it with the +/// Decodes the given [String] buffer as a picture, associating it with the /// given scale. /// /// The provided [bytes] buffer should not be changed after it is provided -/// to a [MemoryImage]. To provide an [PictureStream] that represents an image +/// to a [MemoryPicture]. To provide an [PictureStream] that represents a picture /// that changes over time, consider creating a new subclass of [ImageProvider] /// whose [load] method returns a subclass of [PictureStreamCompleter] that can /// handle providing multiple images. /// /// See also: /// -/// * [Image.memory] for a shorthand of an [Image] widget backed by [MemoryImage]. +/// * [SvgPicture.memory] for a shorthand of an [SvgPicture] widget backed by [MemoryPicture]. class MemoryPicture extends PictureProvider { - /// Creates an object that decodes a [Uint8List] buffer as an image. + /// Creates an object that decodes a [Uint8List] buffer as a picture. /// /// The arguments must not be null. const MemoryPicture(this.decoder, this.bytes) : assert(bytes != null); - final PictureInfoDecoder decoder; + final PictureInfoDecoder decoder; - /// The bytes to decode into an image. + /// The bytes to decode into a picture. final Uint8List bytes; @override @@ -553,9 +554,9 @@ class MemoryPicture extends PictureProvider { return new OneFramePictureStreamCompleter(_loadAsync(key)); } - Future _loadAsync(MemoryPicture key) { + Future _loadAsync(MemoryPicture key) async { assert(key == this); - return decoder(bytes); + return await decoder(bytes); } @override @@ -574,7 +575,49 @@ class MemoryPicture extends PictureProvider { String toString() => '$runtimeType(${describeIdentity(bytes)})'; } -/// Fetches an image from an [AssetBundle], associating it with the given scale. +class StringPicture extends PictureProvider { + /// Creates an object that decodes a [Uint8List] buffer as a picture. + /// + /// The arguments must not be null. + const StringPicture(this.decoder, this.string) : assert(string != null); + + final PictureInfoDecoder decoder; + + /// The string to decode into a picture. + final String string; + + @override + Future obtainKey() { + return new SynchronousFuture(this); + } + + @override + PictureStreamCompleter load(StringPicture key) { + return new OneFramePictureStreamCompleter(_loadAsync(key)); + } + + Future _loadAsync(StringPicture key) async { + assert(key == this); + return await decoder(string); + } + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + final StringPicture typedOther = other; + return string == typedOther.string; + } + + @override + int get hashCode => string.hashCode; + + @override + String toString() => '$runtimeType($string)'; +} + +/// Fetches a picture from an [AssetBundle], associating it with the given scale. /// /// This implementation requires an explicit final [assetName] and [scale] on /// construction, and ignores the device pixel ratio and size in the @@ -584,9 +627,9 @@ class MemoryPicture extends PictureProvider { /// /// ## Fetching assets /// -/// When fetching an image provided by the app itself, use the [assetName] +/// When fetching a picture provided by the app itself, use the [assetName] /// argument to name the asset to choose. For instance, consider a directory -/// `icons` with an image `heart.png`. First, the [pubspec.yaml] of the project +/// `icons` with a picture `heart.png`. First, the [pubspec.yaml] of the project /// should specify its assets in the `flutter` section: /// /// ```yaml @@ -656,7 +699,7 @@ class ExactAssetPicture extends AssetBundlePictureProvider { /// included in a package. See the documentation for the [ExactAssetImage] class /// itself for details. const ExactAssetPicture( - PictureInfoDecoder decoder, + PictureInfoDecoder decoder, this.assetName, { this.bundle, this.package, diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart index 0b1e5b92371f..877b8be21724 100644 --- a/third_party/lib/src/picture_stream.dart +++ b/third_party/lib/src/picture_stream.dart @@ -39,32 +39,32 @@ class PictureInfo { /// Signature for callbacks reporting that an image is available. /// -/// Used by [ImageStream]. +/// Used by [PictureStream]. /// /// The `synchronousCall` argument is true if the listener is being invoked /// during the call to addListener. This can be useful if, for example, -/// [ImageStream.addListener] is invoked during a frame, so that a new rendering +/// [PictureStream.addListener] is invoked during a frame, so that a new rendering /// frame is requested if the call was asynchronous (after the current frame) /// and no rendering frame is requested if the call was synchronous (within the -/// same stack frame as the call to [ImageStream.addListener]). +/// same stack frame as the call to [PictureStream.addListener]). typedef void PictureListener(PictureInfo image, bool synchronousCall); /// A handle to an image resource. /// -/// ImageStream represents a handle to a [dart:ui.Image] object and its scale +/// PictureStream represents a handle to a [dart:ui.Image] object and its scale /// (together represented by an [ImageInfo] object). The underlying image object /// might change over time, either because the image is animating or because the /// underlying image resource was mutated. /// -/// ImageStream objects can also represent an image that hasn't finished +/// PictureStream objects can also represent an image that hasn't finished /// loading. /// -/// ImageStream objects are backed by [PictureStreamCompleter] objects. +/// PictureStream objects are backed by [PictureStreamCompleter] objects. /// /// See also: /// -/// * [ImageProvider], which has an example that includes the use of an -/// [ImageStream] in a [Widget]. +/// * [PictureProvider], which has an example that includes the use of an +/// [PictureStream] in a [Widget]. class PictureStream extends Diagnosticable { /// Create an initially unbound image stream. /// @@ -79,12 +79,12 @@ class PictureStream extends Diagnosticable { List _listeners; - /// Assigns a particular [PictureStreamCompleter] to this [ImageStream]. + /// Assigns a particular [PictureStreamCompleter] to this [PictureStream]. /// - /// This is usually done automatically by the [ImageProvider] that created the - /// [ImageStream]. + /// This is usually done automatically by the [PictureProvider] that created the + /// [PictureStream]. /// - /// This method can only be called once per stream. To have an [ImageStream] + /// This method can only be called once per stream. To have an [PictureStream] /// represent multiple images over time, assign it a completer that /// completes several images in succession. void setCompleter(PictureStreamCompleter value) { @@ -126,14 +126,14 @@ class PictureStream extends Diagnosticable { } /// Returns an object which can be used with `==` to determine if this - /// [ImageStream] shares the same listeners list as another [ImageStream]. + /// [PictureStream] shares the same listeners list as another [PictureStream]. /// /// This can be used to avoid unregistering and reregistering listeners after - /// calling [ImageProvider.resolve] on a new, but possibly equivalent, - /// [ImageProvider]. + /// calling [PictureProvider.resolve] on a new, but possibly equivalent, + /// [PictureProvider]. /// /// The key may change once in the lifetime of the object. When it changes, it - /// will go from being different than other [ImageStream]'s keys to + /// will go from being different than other [PictureStream]'s keys to /// potentially being the same as others'. No notification is sent when this /// happens. Object get key => _completer != null ? _completer : this; @@ -159,11 +159,11 @@ class PictureStream extends Diagnosticable { } } -/// Base class for those that manage the loading of [dart:ui.Image] objects for -/// [ImageStream]s. +/// Base class for those that manage the loading of [dart:ui.Picture] objects for +/// [PictureStream]s. /// -/// [ImageStreamListener] objects are rarely constructed directly. Generally, an -/// [ImageProvider] subclass will return an [ImageStream] and automatically +/// [PictureStreamListener] objects are rarely constructed directly. Generally, an +/// [PictureProvider] subclass will return an [PictureStream] and automatically /// configure it with the right [PictureStreamCompleter] when possible. abstract class PictureStreamCompleter extends Diagnosticable { final List _listeners = []; @@ -239,10 +239,10 @@ abstract class PictureStreamCompleter extends Diagnosticable { } } -/// Manages the loading of [dart:ui.Image] objects for static [ImageStream]s (those +/// Manages the loading of [dart:ui.Image] objects for static [PictureStream]s (those /// with only one frame). class OneFramePictureStreamCompleter extends PictureStreamCompleter { - /// Creates a manager for one-frame [ImageStream]s. + /// Creates a manager for one-frame [PictureStream]s. /// /// The image resource awaits the given [Future]. When the future resolves, /// it notifies the [PictureListener]s that have been registered with diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index e30d3889cba2..d78c92b25d5d 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -106,13 +106,26 @@ class SvgImage extends VectorDrawableImage { } } -PictureInfo svgPictureDecoder(Uint8List raw) { - final DrawableRoot svg = fromSvgBytes(raw); +FutureOr svgPictureDecoder(Uint8List raw) async { + final DrawableRoot svg = await fromSvgBytes(raw); return new PictureInfo(picture: svg.toPicture(), viewBox: svg.viewBox); } -DrawableRoot fromSvgBytes(Uint8List raw) { - return fromSvgString(utf8.decode(raw)); +FutureOr svgPictureStringDecoder(String raw) { + final DrawableRoot svg = fromSvgString(raw); + return new PictureInfo(picture: svg.toPicture(), viewBox: svg.viewBox); +} + +FutureOr fromSvgBytes(Uint8List raw) async { + // See: https://github.com/dart-lang/sdk/issues/31954 + // See: https://github.com/flutter/flutter/blob/bf3bd7667f07709d0b817ebfcb6972782cfef637/packages/flutter/lib/src/services/asset_bundle.dart#L66 + if (raw.lengthInBytes < 20 * 1024) { + return fromSvgString(utf8.decode(raw)); + } else { + final String str = await compute((Uint8List data) => utf8.decode(data), raw, + debugLabel: 'UTF8 decode for SVG'); + return fromSvgString(str); + } } /// Creates a [DrawableRoot] from a string of SVG data. @@ -199,27 +212,30 @@ class SvgPicture extends StatefulWidget { this.matchTextDirection = false, AssetBundle bundle, String package}) - : pictureProvider = new ExactAssetPicture(svgDecoder, assetName, + : pictureProvider = new ExactAssetPicture(svgByteDecoder, assetName, bundle: bundle, package: package), super(key: key); SvgPicture.network(String url, this.width, this.height, {Key key, Map headers, this.matchTextDirection = false}) - : pictureProvider = new NetworkPicture(svgDecoder, url, headers: headers), + : pictureProvider = + new NetworkPicture(svgByteDecoder, url, headers: headers), super(key: key); SvgPicture.file(File file, this.width, this.height, {Key key, this.matchTextDirection = false}) - : pictureProvider = new FilePicture(svgDecoder, file), + : pictureProvider = new FilePicture(svgByteDecoder, file), super(key: key); SvgPicture.memory(Uint8List bytes, this.width, this.height, {Key key, this.matchTextDirection = false}) - : pictureProvider = new MemoryPicture(svgDecoder, bytes), + : pictureProvider = new MemoryPicture(svgByteDecoder, bytes), super(key: key); - static final PictureInfoDecoder svgDecoder = + static final PictureInfoDecoder svgByteDecoder = (Uint8List bytes) => svgPictureDecoder(bytes); + static final PictureInfoDecoder svgStringDecoder = + (String bytes) => svgPictureStringDecoder(bytes); final PictureProvider pictureProvider; final double width; diff --git a/third_party/lib/vector_drawable.dart b/third_party/lib/vector_drawable.dart index 7320d88d3e0b..4781646d27ca 100644 --- a/third_party/lib/vector_drawable.dart +++ b/third_party/lib/vector_drawable.dart @@ -77,8 +77,7 @@ class VectorDrawableImage extends StatelessWidget { stack: StackTrace.current, )); } else if (snapShot.hasData) { - final CustomPainter painter = - new VectorPainter(snapShot.data); + final CustomPainter painter = new VectorPainter(snapShot.data); return new RepaintBoundary.wrap( CustomPaint( painter: paintLocation == PaintLocation.background @@ -100,4 +99,3 @@ class VectorDrawableImage extends StatelessWidget { ); } } - diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index c8d3fe2eed2b..60a89fb66d94 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -1,6 +1,7 @@ import 'dart:async'; +import 'dart:convert'; import 'dart:io'; -import 'dart:ui'; +import 'dart:typed_data'; import 'package:flutter/widgets.dart'; import 'package:flutter/services.dart'; @@ -9,7 +10,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:mockito/mockito.dart'; void main() { - const String svg = ''' + final Uint8List svg = utf8.encode(''' -'''; +'''); - testWidgets('SvgImage.fromString', (WidgetTester tester) async { + testWidgets('SvgPicture.memory', (WidgetTester tester) async { final GlobalKey key = new GlobalKey(); - await tester.pumpWidget(new SvgImage.fromString( + await tester.pumpWidget(new SvgPicture.memory( svg, - const Size(100.0, 100.0), + 100.0, + 100.0, key: key, )); expect(find.byKey(key), findsOneWidget); }); - testWidgets('SvgImage.asset', (WidgetTester tester) async { + testWidgets('SvgPicture.asset', (WidgetTester tester) async { final MockAssetBundle mockAsset = new MockAssetBundle(); - when(mockAsset.loadString('test.svg')) - .thenAnswer((_) => new Future.value(svg)); + when(mockAsset.load('test.svg')).thenAnswer( + (_) => new Future.value(new ByteData.view(svg.buffer))); final GlobalKey key = new GlobalKey(); - await tester.pumpWidget(new SvgImage.asset( + await tester.pumpWidget(new SvgPicture.asset( 'test.svg', - const Size(100.0, 100.0), + 100.0, + 100.0, key: key, bundle: mockAsset, )); @@ -61,19 +64,19 @@ void main() { when(mockRequest.close()).thenAnswer( (_) => new Future.value(mockResponse)); - when(mockResponse.transform(typed(any))) - .thenAnswer((_) => new Stream.fromIterable([svg])); + when(mockResponse.transform(typed(any))) + .thenAnswer((_) => new Stream.fromIterable([svg])); when(mockResponse.listen(typed(any), onDone: typed(any, named: 'onDone'), onError: typed(any, named: 'onError'), cancelOnError: typed(any, named: 'cancelOnError'))) .thenAnswer((Invocation invocation) { - final void Function(String) onData = invocation.positionalArguments[0]; + final void Function(Uint8List) onData = invocation.positionalArguments[0]; final void Function(Object) onError = invocation.namedArguments[#onError]; final void Function() onDone = invocation.namedArguments[#onDone]; final bool cancelOnError = invocation.namedArguments[#cancelOnError]; - return new Stream.fromIterable([svg]).listen( + return new Stream.fromIterable([svg]).listen( onData, onDone: onDone, onError: onError, @@ -81,27 +84,30 @@ void main() { ); }); - testWidgets('SvgImage.network', (WidgetTester tester) async { + testWidgets('SvgPicture.network', (WidgetTester tester) async { HttpOverrides.runZoned(() async { when(mockResponse.statusCode).thenReturn(200); final GlobalKey key = new GlobalKey(); - await tester.pumpWidget(new SvgImage.network( + await tester.pumpWidget(new SvgPicture.network( 'test.svg', - const Size(100.0, 100.0), + 100.0, + 100.0, key: key, )); expect(find.byKey(key), findsOneWidget); }, createHttpClient: (SecurityContext c) => mockHttpClient); }); - // TODO: Why isn't this working when I just use SvgImage.network? - test('loadNetworkAsset HTTP exception', () { - HttpOverrides.runZoned(() { - when(mockResponse.statusCode).thenReturn(400); - expect(() => loadNetworkAsset('test.svg'), - throwsA(const isInstanceOf())); - }, createHttpClient: (SecurityContext c) => mockHttpClient); - }); + // // TODO: Why isn't this working when I just use SvgPicture.network? + // testWidgets('SvgPicture.network HTTP exception', (WidgetTester tester) async { + // HttpOverrides.runZoned(() async { + // when(mockResponse.statusCode).thenReturn(400); + // expect(() async { + // Future t = await tester + // .pumpWidget(new SvgPicture.network('test.svg', 100.0, 100.0)); + // }, throwsA(const isInstanceOf())); + // }, createHttpClient: (SecurityContext c) => mockHttpClient); + // }); } class MockAssetBundle extends Mock implements AssetBundle {} From 346680a20c3a011aed53be9e1c4b7a1b17b3308a Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 25 May 2018 14:50:47 -0400 Subject: [PATCH 082/512] initial caching --- third_party/example/main.dart | 3 +- third_party/lib/src/picture_cache.dart | 71 ++++++++ third_party/lib/src/picture_provider.dart | 11 +- third_party/lib/src/render_picture.dart | 4 - third_party/lib/svg.dart | 206 +++++++++++----------- third_party/pubspec.lock | 15 +- third_party/pubspec.yaml | 6 + third_party/test/widget_svg_test.dart | 6 - third_party/tool/gen_golden.dart | 2 +- 9 files changed, 202 insertions(+), 122 deletions(-) create mode 100644 third_party/lib/src/picture_cache.dart diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 349a0b6d140e..f66efd287ea3 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -87,7 +87,7 @@ class _MyHomePageState extends State { for (String assetName in assetNames) { _painters.add( - new SvgPicture.asset(assetName, _dimension, _dimension), + new SvgPicture.asset(assetName), ); } @@ -95,7 +95,6 @@ class _MyHomePageState extends State { _painters.add( new SvgPicture.network( uriName, - _dimension, _dimension, // loadingPlaceholderBuilder: (BuildContext context) => new Container( // padding: const EdgeInsets.all(30.0), // child: const CircularProgressIndicator()), diff --git a/third_party/lib/src/picture_cache.dart b/third_party/lib/src/picture_cache.dart new file mode 100644 index 000000000000..86d3ccbcbe46 --- /dev/null +++ b/third_party/lib/src/picture_cache.dart @@ -0,0 +1,71 @@ +import 'picture_stream.dart'; + +const int _kDefaultSize = 1000; + +// TODO: Implement memory based limiting, once `approximateByteCount` is exposed in engine +class PictureCache { + final Map _cache = {}; + + /// Maximum number of entries to store in the cache. + /// + /// Once this many entries have been cached, the least-recently-used entry is + /// evicted when adding a new entry. + int get maximumSize => _maximumSize; + int _maximumSize = _kDefaultSize; + /// Changes the maximum cache size. + /// + /// If the new size is smaller than the current number of elements, the + /// extraneous elements are evicted immediately. Setting this to zero and then + /// returning it to its original value will therefore immediately clear the + /// cache. + set maximumSize(int value) { + assert(value != null); + assert(value >= 0); + if (value == maximumSize) + return; + _maximumSize = value; + if (maximumSize == 0) { + _cache.clear(); + } else { + while (_cache.length > maximumSize) + _cache.remove(_cache.keys.first); + } + } + + /// Evicts all entries from the cache. + /// + /// This is useful if, for instance, the root asset bundle has been updated + /// and therefore new images must be obtained. + // TODO(ianh): Provide a way to target individual images. This is currently non-trivial + // because by the time we get to the imageCache, the keys we're using are opaque. + void clear() { + _cache.clear(); + } + + /// Returns the previously cached [ImageStream] for the given key, if available; + /// if not, calls the given callback to obtain it first. In either case, the + /// key is moved to the "most recently used" position. + /// + /// The arguments must not be null. The `loader` cannot return null. + PictureStreamCompleter putIfAbsent(Object key, PictureStreamCompleter loader()) { + print(_cache.keys.length); + assert(key != null); + assert(loader != null); + PictureStreamCompleter result = _cache[key]; + if (result != null) { + // Remove the provider from the list so that we can put it back in below + // and thus move it to the end of the list. + _cache.remove(key); + } else { + if (_cache.length == maximumSize && maximumSize > 0) + _cache.remove(_cache.keys.first); + result = loader(); + } + if (maximumSize > 0) { + assert(_cache.length < maximumSize); + _cache[key] = result; + } + assert(_cache.length <= maximumSize); + return result; + } +} \ No newline at end of file diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 459e8dddbbdf..8ffb44e942d9 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -10,14 +10,11 @@ import 'dart:ui' show Rect, Locale, TextDirection, hashValues; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; -// TODO: make this less SVG specific -// import '../svg.dart'; +import 'picture_cache.dart'; import 'picture_stream.dart'; -// import 'vector_drawable.dart'; typedef FutureOr PictureInfoDecoder(T data); - /// Configuration information passed to the [ImageProvider.resolve] method to /// select a specific image. /// @@ -161,6 +158,8 @@ class PictureConfiguration { } } +PictureCache _cache = new PictureCache(); + /// Identifies a picture without committing to the precise final asset. This /// allows a set of images to be identified and for the precise image to later /// be resolved based on the environment, e.g. the device pixel ratio. @@ -274,9 +273,9 @@ abstract class PictureProvider { T obtainedKey; obtainKey().then((T key) { obtainedKey = key; - stream.setCompleter(load(key)); + //stream.setCompleter(load(key)); // stream.setCompleter(PaintingBinding.instance.imageCache - // .putIfAbsent(key, () => load(key))); + stream.setCompleter(_cache.putIfAbsent(key, () => load(key))); }).catchError((dynamic exception, StackTrace stack) async { FlutterError.reportError(new FlutterErrorDetails( exception: exception, diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index 03c17df2b1c5..00a4d4ac440e 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -8,15 +8,11 @@ class RawPicture extends LeafRenderObjectWidget { const RawPicture( this.picture, { Key key, - this.width, - this.height, this.matchTextDirection = false, this.textDirection, }) : super(key: key); final PictureInfo picture; - final double width; - final double height; final bool matchTextDirection; final TextDirection textDirection; diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index d78c92b25d5d..53945f06efcb 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; +import 'dart:ui' show Picture; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart' show rootBundle, AssetBundle; @@ -38,7 +39,7 @@ class SvgImage extends VectorDrawableImage { color: color, colorBlendMode: colorBlendMode); - factory SvgImage.fromString(String svg, Size size, + factory SvgImage.fromString(String svgString, Size size, {Key key, PaintLocation paintLocation = PaintLocation.background, Widget child, @@ -47,7 +48,7 @@ class SvgImage extends VectorDrawableImage { Color color, BlendMode colorBlendMode}) { return new SvgImage._( - new Future.value(fromSvgString(svg)), + new Future.value(svg.fromSvgString(svgString)), size, child: child, key: key, @@ -71,7 +72,7 @@ class SvgImage extends VectorDrawableImage { Color color, BlendMode colorBlendMode}) { return new SvgImage._( - loadAsset(assetName, bundle: bundle, package: package), + svg.loadAsset(assetName, bundle: bundle, package: package), size, child: child, key: key, @@ -94,7 +95,7 @@ class SvgImage extends VectorDrawableImage { Color color, BlendMode colorBlendMode}) { return new SvgImage._( - loadNetworkAsset(uri, + svg.loadNetworkAsset(uri, colorFilter: ColorFilter.mode(color, colorBlendMode)), size, child: child, @@ -106,108 +107,119 @@ class SvgImage extends VectorDrawableImage { } } -FutureOr svgPictureDecoder(Uint8List raw) async { - final DrawableRoot svg = await fromSvgBytes(raw); - return new PictureInfo(picture: svg.toPicture(), viewBox: svg.viewBox); -} +final Svg svg = new Svg._(); -FutureOr svgPictureStringDecoder(String raw) { - final DrawableRoot svg = fromSvgString(raw); - return new PictureInfo(picture: svg.toPicture(), viewBox: svg.viewBox); -} +class Svg { + Svg._(); + + FutureOr svgPictureDecoder(Uint8List raw) async { + final DrawableRoot svgRoot = await fromSvgBytes(raw); + final Picture pic = svgRoot.toPicture(); + return new PictureInfo(picture: pic, viewBox: svgRoot.viewBox); + } -FutureOr fromSvgBytes(Uint8List raw) async { - // See: https://github.com/dart-lang/sdk/issues/31954 - // See: https://github.com/flutter/flutter/blob/bf3bd7667f07709d0b817ebfcb6972782cfef637/packages/flutter/lib/src/services/asset_bundle.dart#L66 - if (raw.lengthInBytes < 20 * 1024) { + FutureOr svgPictureStringDecoder(String raw) { + final DrawableRoot svg = fromSvgString(raw); + return new PictureInfo(picture: svg.toPicture(), viewBox: svg.viewBox); + } + + FutureOr fromSvgBytes(Uint8List raw) async { + // TODO - do utf decoding in another thread? + // Might just have to live with potentially slow(ish) decoding, this is causing errors. + // See: https://github.com/dart-lang/sdk/issues/31954 + // See: https://github.com/flutter/flutter/blob/bf3bd7667f07709d0b817ebfcb6972782cfef637/packages/flutter/lib/src/services/asset_bundle.dart#L66 + // if (raw.lengthInBytes < 20 * 1024) { return fromSvgString(utf8.decode(raw)); - } else { - final String str = await compute((Uint8List data) => utf8.decode(data), raw, - debugLabel: 'UTF8 decode for SVG'); - return fromSvgString(str); + // } else { + // final String str = + // await compute(_utf8Decode, raw, debugLabel: 'UTF8 decode for SVG'); + // return fromSvgString(str); + // } } -} -/// Creates a [DrawableRoot] from a string of SVG data. -DrawableRoot fromSvgString(String rawSvg) { - final XmlElement svg = xml.parse(rawSvg).rootElement; - final Rect viewBox = parseViewBox(svg); - //final Map paintServers = {}; - final DrawableDefinitionServer definitions = new DrawableDefinitionServer(); - final DrawableStyle style = parseStyle(svg, definitions, viewBox, null); - - final List children = svg.children - .where((XmlNode child) => child is XmlElement) - .map( - (XmlNode child) => parseSvgElement( - child, - definitions, - viewBox, - style, - ), - ) - .toList(); - return new DrawableRoot( - viewBox, - children, - definitions, - parseStyle(svg, definitions, viewBox, null), - ); -} + // String _utf8Decode(Uint8List data) { + // return utf8.decode(data); + // } + + /// Creates a [DrawableRoot] from a string of SVG data. + DrawableRoot fromSvgString(String rawSvg) { + final XmlElement svg = xml.parse(rawSvg).rootElement; + final Rect viewBox = parseViewBox(svg); + //final Map paintServers = {}; + final DrawableDefinitionServer definitions = new DrawableDefinitionServer(); + final DrawableStyle style = parseStyle(svg, definitions, viewBox, null); + + final List children = svg.children + .where((XmlNode child) => child is XmlElement) + .map( + (XmlNode child) => parseSvgElement( + child, + definitions, + viewBox, + style, + ), + ) + .toList(); + return new DrawableRoot( + viewBox, + children, + definitions, + parseStyle(svg, definitions, viewBox, null), + ); + } -/// Creates a [DrawableRoot] from a bundled asset. -@deprecated -Future loadAsset(String assetName, - {AssetBundle bundle, String package}) async { - bundle ??= rootBundle; - final String rawSvg = await bundle.loadString( - package == null ? assetName : 'packages/$package/$assetName', - ); - return fromSvgString(rawSvg); -} + /// Creates a [DrawableRoot] from a bundled asset. + @deprecated + Future loadAsset(String assetName, + {AssetBundle bundle, String package}) async { + bundle ??= rootBundle; + final String rawSvg = await bundle.loadString( + package == null ? assetName : 'packages/$package/$assetName', + ); + return fromSvgString(rawSvg); + } -@deprecated -final HttpClient _httpClient = new HttpClient(); + @deprecated + final HttpClient _httpClient = new HttpClient(); -/// Creates a [DrawableRoot] from a network asset with an HTTP get request. -@deprecated -Future loadNetworkAsset(String url, - {ColorFilter colorFilter}) async { - final Uri uri = Uri.base.resolve(url); - final HttpClientRequest request = await _httpClient.getUrl(uri); - final HttpClientResponse response = await request.close(); - - if (response.statusCode != HttpStatus.OK) { - throw new HttpException('Could not get network SVG asset', uri: uri); + /// Creates a [DrawableRoot] from a network asset with an HTTP get request. + @deprecated + Future loadNetworkAsset(String url, + {ColorFilter colorFilter}) async { + final Uri uri = Uri.base.resolve(url); + final HttpClientRequest request = await _httpClient.getUrl(uri); + final HttpClientResponse response = await request.close(); + + if (response.statusCode != HttpStatus.OK) { + throw new HttpException('Could not get network SVG asset', uri: uri); + } + final String rawSvg = await _consolidateHttpClientResponse(response); + + return fromSvgString(rawSvg); } - final String rawSvg = await _consolidateHttpClientResponse(response); - return fromSvgString(rawSvg); -} + @deprecated + Future _consolidateHttpClientResponse( + HttpClientResponse response) async { + final Completer completer = new Completer.sync(); + final StringBuffer buffer = new StringBuffer(); -@deprecated -Future _consolidateHttpClientResponse( - HttpClientResponse response) async { - final Completer completer = new Completer.sync(); - final StringBuffer buffer = new StringBuffer(); - - response.transform(utf8.decoder).listen((String chunk) { - buffer.write(chunk); - }, onDone: () { - completer.complete(buffer.toString()); - }, onError: completer.completeError, cancelOnError: true); - - return completer.future; -} + response.transform(utf8.decoder).listen((String chunk) { + buffer.write(chunk); + }, onDone: () { + completer.complete(buffer.toString()); + }, onError: completer.completeError, cancelOnError: true); -Image icon; + return completer.future; + } +} class SvgPicture extends StatefulWidget { - const SvgPicture(this.pictureProvider, this.width, this.height, + const SvgPicture(this.pictureProvider, {Key key, this.matchTextDirection = false}) : super(key: key); - SvgPicture.asset(String assetName, this.width, this.height, + SvgPicture.asset(String assetName, {Key key, this.matchTextDirection = false, AssetBundle bundle, @@ -216,30 +228,26 @@ class SvgPicture extends StatefulWidget { bundle: bundle, package: package), super(key: key); - SvgPicture.network(String url, this.width, this.height, + SvgPicture.network(String url, {Key key, Map headers, this.matchTextDirection = false}) : pictureProvider = new NetworkPicture(svgByteDecoder, url, headers: headers), super(key: key); - SvgPicture.file(File file, this.width, this.height, - {Key key, this.matchTextDirection = false}) + SvgPicture.file(File file, {Key key, this.matchTextDirection = false}) : pictureProvider = new FilePicture(svgByteDecoder, file), super(key: key); - SvgPicture.memory(Uint8List bytes, this.width, this.height, - {Key key, this.matchTextDirection = false}) + SvgPicture.memory(Uint8List bytes, {Key key, this.matchTextDirection = false}) : pictureProvider = new MemoryPicture(svgByteDecoder, bytes), super(key: key); static final PictureInfoDecoder svgByteDecoder = - (Uint8List bytes) => svgPictureDecoder(bytes); + (Uint8List bytes) => svg.svgPictureDecoder(bytes); static final PictureInfoDecoder svgStringDecoder = - (String bytes) => svgPictureStringDecoder(bytes); + (String bytes) => svg.svgPictureStringDecoder(bytes); final PictureProvider pictureProvider; - final double width; - final double height; final bool matchTextDirection; @override @@ -338,8 +346,6 @@ class _SvgPictureState extends State { Widget build(BuildContext context) { return new RawPicture( _picture, - width: widget.width, - height: widget.height, matchTextDirection: widget.matchTextDirection, ); } diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index d6a60768cbb9..66fa45a4c95d 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -278,9 +278,18 @@ packages: source: hosted version: "0.2.2" sky_engine: - dependency: transitive - description: flutter - source: sdk + dependency: "direct overridden" + description: + path: "/Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_engine" + relative: false + source: path + version: "0.0.99" + sky_services: + dependency: "direct overridden" + description: + path: "/Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_services" + relative: false + source: path version: "0.0.99" source_map_stack_trace: dependency: transitive diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 65cbd186897f..6e4ee3309438 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -67,3 +67,9 @@ flutter: environment: sdk: ">=1.19.0 <3.0.0" flutter: ">=0.3.6 <2.0.0" + +dependency_overrides: + sky_engine: + path: /Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_engine + sky_services: + path: /Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_services diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 60a89fb66d94..f71984e8ac55 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -31,8 +31,6 @@ void main() { final GlobalKey key = new GlobalKey(); await tester.pumpWidget(new SvgPicture.memory( svg, - 100.0, - 100.0, key: key, )); expect(find.byKey(key), findsOneWidget); @@ -46,8 +44,6 @@ void main() { final GlobalKey key = new GlobalKey(); await tester.pumpWidget(new SvgPicture.asset( 'test.svg', - 100.0, - 100.0, key: key, bundle: mockAsset, )); @@ -90,8 +86,6 @@ void main() { final GlobalKey key = new GlobalKey(); await tester.pumpWidget(new SvgPicture.network( 'test.svg', - 100.0, - 100.0, key: key, )); expect(find.byKey(key), findsOneWidget); diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index b77e7f1666fd..e1c5896be0eb 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -12,7 +12,7 @@ import 'dart:ui'; import 'package:path/path.dart' as path; -import 'package:flutter_svg/svg.dart' as svg; +import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/src/vector_drawable.dart'; Future getSvgPngBytes(String svgData) async { From 1bf4e0d9698d70f10c269fb590b51fe4e7fc7ec8 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 25 May 2018 14:57:47 -0400 Subject: [PATCH 083/512] Update pubspec.yaml --- third_party/pubspec.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 6e4ee3309438..3b57193361c9 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -68,8 +68,8 @@ environment: sdk: ">=1.19.0 <3.0.0" flutter: ">=0.3.6 <2.0.0" -dependency_overrides: - sky_engine: - path: /Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_engine - sky_services: - path: /Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_services +#dependency_overrides: +# sky_engine: +# path: /Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_engine +# sky_services: +# path: /Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_services From 5cc51e561d9fdf881e637e31e7ed83a8c8ddddd6 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 25 May 2018 15:02:44 -0400 Subject: [PATCH 084/512] format --- third_party/lib/src/picture_cache.dart | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/third_party/lib/src/picture_cache.dart b/third_party/lib/src/picture_cache.dart index 86d3ccbcbe46..88cc2c18b2a1 100644 --- a/third_party/lib/src/picture_cache.dart +++ b/third_party/lib/src/picture_cache.dart @@ -4,7 +4,8 @@ const int _kDefaultSize = 1000; // TODO: Implement memory based limiting, once `approximateByteCount` is exposed in engine class PictureCache { - final Map _cache = {}; + final Map _cache = + {}; /// Maximum number of entries to store in the cache. /// @@ -12,6 +13,7 @@ class PictureCache { /// evicted when adding a new entry. int get maximumSize => _maximumSize; int _maximumSize = _kDefaultSize; + /// Changes the maximum cache size. /// /// If the new size is smaller than the current number of elements, the @@ -21,14 +23,12 @@ class PictureCache { set maximumSize(int value) { assert(value != null); assert(value >= 0); - if (value == maximumSize) - return; + if (value == maximumSize) return; _maximumSize = value; if (maximumSize == 0) { _cache.clear(); } else { - while (_cache.length > maximumSize) - _cache.remove(_cache.keys.first); + while (_cache.length > maximumSize) _cache.remove(_cache.keys.first); } } @@ -47,8 +47,8 @@ class PictureCache { /// key is moved to the "most recently used" position. /// /// The arguments must not be null. The `loader` cannot return null. - PictureStreamCompleter putIfAbsent(Object key, PictureStreamCompleter loader()) { - print(_cache.keys.length); + PictureStreamCompleter putIfAbsent( + Object key, PictureStreamCompleter loader()) { assert(key != null); assert(loader != null); PictureStreamCompleter result = _cache[key]; @@ -68,4 +68,4 @@ class PictureCache { assert(_cache.length <= maximumSize); return result; } -} \ No newline at end of file +} From 3dcffdb60024b01ec259959fe0947f807d50b133 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 26 May 2018 22:58:41 -0400 Subject: [PATCH 085/512] allow drawing outside of viewbox --- third_party/lib/src/picture_provider.dart | 70 +++++++++++------------ third_party/lib/src/render_picture.dart | 42 ++++++++++---- third_party/lib/svg.dart | 29 ++++++---- 3 files changed, 85 insertions(+), 56 deletions(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 8ffb44e942d9..10825cb3e70e 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -15,18 +15,18 @@ import 'picture_stream.dart'; typedef FutureOr PictureInfoDecoder(T data); -/// Configuration information passed to the [ImageProvider.resolve] method to +/// Configuration information passed to the [PictureProvider.resolve] method to /// select a specific image. /// /// See also: /// -/// * [createLocalImageConfiguration], which creates an [ImageConfiguration] +/// * [createLocalPictureConfiguration], which creates an [PictureConfiguration] /// based on ambient configuration in a [Widget] environment. -/// * [ImageProvider], which uses [ImageConfiguration] objects to determine +/// * [PictureProvider], which uses [PictureConfiguration] objects to determine /// which image to obtain. @immutable class PictureConfiguration { - /// Creates an object holding the configuration information for an [ImageProvider]. + /// Creates an object holding the configuration information for an [PictureProvider]. /// /// All the arguments are optional. Configuration information is merely /// advisory and best-effort. @@ -39,7 +39,7 @@ class PictureConfiguration { this.platform, }); - /// Creates an object holding the configuration information for an [ImageProvider]. + /// Creates an object holding the configuration information for an [PictureProvider]. /// /// All the arguments are optional. Configuration information is merely /// advisory and best-effort. @@ -61,7 +61,7 @@ class PictureConfiguration { ); } - /// The preferred [AssetBundle] to use if the [ImageProvider] needs one and + /// The preferred [AssetBundle] to use if the [PictureProvider] needs one and /// does not have one already selected. final AssetBundle bundle; @@ -85,7 +85,7 @@ class PictureConfiguration { /// a picture configuration that provides no additional information. /// - /// Useful when resolving an [ImageProvider] without any context. + /// Useful when resolving an [PictureProvider] without any context. static const PictureConfiguration empty = const PictureConfiguration(); @override @@ -109,7 +109,7 @@ class PictureConfiguration { @override String toString() { final StringBuffer result = new StringBuffer(); - result.write('ImageConfiguration('); + result.write('PictureConfiguration('); bool hasArguments = false; if (bundle != null) { if (hasArguments) { @@ -164,37 +164,37 @@ PictureCache _cache = new PictureCache(); /// allows a set of images to be identified and for the precise image to later /// be resolved based on the environment, e.g. the device pixel ratio. /// -/// To obtain an [PictureStream] from an [ImageProvider], call [resolve], -/// passing it an [ImageConfiguration] object. +/// To obtain an [PictureStream] from an [PictureProvider], call [resolve], +/// passing it an [PictureConfiguration] object. /// -/// [ImageProvider] uses the global [imageCache] to cache images. +/// [PictureProvider] uses the global [imageCache] to cache images. /// /// The type argument `T` is the type of the object used to represent a resolved /// configuration. This is also the type used for the key in the image cache. It /// should be immutable and implement the [==] operator and the [hashCode] -/// getter. Subclasses should subclass a variant of [ImageProvider] with an +/// getter. Subclasses should subclass a variant of [PictureProvider] with an /// explicit `T` type argument. /// /// The type argument does not have to be specified when using the type as an -/// argument (where any image provider is acceptable). +/// argument (where any Picture provider is acceptable). /// /// The following image formats are supported: {@macro flutter.dart:ui.imageFormats} /// /// ## Sample code /// /// The following shows the code required to write a widget that fully conforms -/// to the [ImageProvider] and [Widget] protocols. (It is essentially a +/// to the [PictureProvider] and [Widget] protocols. (It is essentially a /// bare-bones version of the [widgets.Image] widget.) /// /// ```dart /// class MyImage extends StatefulWidget { /// const MyImage({ /// Key key, -/// @required this.imageProvider, -/// }) : assert(imageProvider != null), +/// @required this.PictureProvider, +/// }) : assert(PictureProvider != null), /// super(key: key); /// -/// final ImageProvider imageProvider; +/// final PictureProvider PictureProvider; /// /// @override /// _MyImageState createState() => new _MyImageState(); @@ -207,7 +207,7 @@ PictureCache _cache = new PictureCache(); /// @override /// void didChangeDependencies() { /// super.didChangeDependencies(); -/// // We call _getImage here because createLocalImageConfiguration() needs to +/// // We call _getImage here because createLocalPictureConfiguration() needs to /// // be called again if the dependencies changed, in case the changes relate /// // to the DefaultAssetBundle, MediaQuery, etc, which that method uses. /// _getImage(); @@ -216,13 +216,13 @@ PictureCache _cache = new PictureCache(); /// @override /// void didUpdateWidget(MyImage oldWidget) { /// super.didUpdateWidget(oldWidget); -/// if (widget.imageProvider != oldWidget.imageProvider) +/// if (widget.PictureProvider != oldWidget.PictureProvider) /// _getImage(); /// } /// /// void _getImage() { /// final PictureStream oldPictureStream = _PictureStream; -/// _PictureStream = widget.imageProvider.resolve(createLocalImageConfiguration(context)); +/// _PictureStream = widget.PictureProvider.resolve(createLocalPictureConfiguration(context)); /// if (_PictureStream.key != oldPictureStream?.key) { /// // If the keys are the same, then we got the same image back, and so we don't /// // need to update the listeners. If the key changed, though, we must make sure @@ -260,10 +260,10 @@ abstract class PictureProvider { /// const constructors so that they can be used in const expressions. const PictureProvider(); - /// Resolves this image provider using the given `configuration`, returning + /// Resolves this Picture provider using the given `configuration`, returning /// an [PictureStream]. /// - /// This is the public entry-point of the [ImageProvider] class hierarchy. + /// This is the public entry-point of the [PictureProvider] class hierarchy. /// /// Subclasses should implement [obtainKey] and [load], which are used by this /// method. @@ -284,9 +284,9 @@ abstract class PictureProvider { context: 'while resolving a picture', silent: true, // could be a network error or whatnot informationCollector: (StringBuffer information) { - information.writeln('Image provider: $this'); + information.writeln('Picture provider: $this'); if (obtainedKey != null) - information.writeln('Image key: $obtainedKey'); + information.writeln('Picture key: $obtainedKey'); })); return null; }); @@ -298,8 +298,8 @@ abstract class PictureProvider { /// /// The type of the key is determined by the subclass. It is a value that /// unambiguously identifies the image (_including its scale_) that the [load] - /// method will fetch. Different [ImageProvider]s given the same constructor - /// arguments and [ImageConfiguration] objects should return keys that are + /// method will fetch. Different [PictureProvider]s given the same constructor + /// arguments and [PictureConfiguration] objects should return keys that are /// '==' to each other (possibly by using a class for the key that itself /// implements [==]). @protected @@ -352,9 +352,9 @@ class AssetBundlePictureKey { String toString() => '$runtimeType(bundle: $bundle, name: "$name")'; } -/// A subclass of [ImageProvider] that knows about [AssetBundle]s. +/// A subclass of [PictureProvider] that knows about [AssetBundle]s. /// -/// This factors out the common logic of [AssetBundle]-based [ImageProvider] +/// This factors out the common logic of [AssetBundle]-based [PictureProvider] /// classes, simplifying what subclasses must implement to just [obtainKey]. abstract class AssetBundlePictureProvider extends PictureProvider { @@ -370,8 +370,8 @@ abstract class AssetBundlePictureProvider PictureStreamCompleter load(AssetBundlePictureKey key) { return new OneFramePictureStreamCompleter(_loadAsync(key), informationCollector: (StringBuffer information) { - information.writeln('Image provider: $this'); - information.write('Image key: $key'); + information.writeln('Picture provider: $this'); + information.write('Picture key: $key'); }); } @@ -426,8 +426,8 @@ class NetworkPicture extends PictureProvider { PictureStreamCompleter load(NetworkPicture key) { return new OneFramePictureStreamCompleter(_loadAsync(key), informationCollector: (StringBuffer information) { - information.writeln('Image provider: $this'); - information.write('Image key: $key'); + information.writeln('Picture provider: $this'); + information.write('Picture key: $key'); }); } @@ -525,7 +525,7 @@ class FilePicture extends PictureProvider { /// /// The provided [bytes] buffer should not be changed after it is provided /// to a [MemoryPicture]. To provide an [PictureStream] that represents a picture -/// that changes over time, consider creating a new subclass of [ImageProvider] +/// that changes over time, consider creating a new subclass of [PictureProvider] /// whose [load] method returns a subclass of [PictureStreamCompleter] that can /// handle providing multiple images. /// @@ -691,7 +691,7 @@ class ExactAssetPicture extends AssetBundlePictureProvider { /// /// The [assetName] and [scale] arguments must not be null. The [scale] arguments /// defaults to 1.0. The [bundle] argument may be null, in which case the - /// bundle provided in the [ImageConfiguration] passed to the [resolve] call + /// bundle provided in the [PictureConfiguration] passed to the [resolve] call /// will be used instead. /// /// The [package] argument must be non-null when fetching an asset that is @@ -716,7 +716,7 @@ class ExactAssetPicture extends AssetBundlePictureProvider { /// The bundle from which the image will be obtained. /// /// If the provided [bundle] is null, the bundle provided in the - /// [ImageConfiguration] passed to the [resolve] call will be used instead. If + /// [PictureConfiguration] passed to the [resolve] call will be used instead. If /// that is also null, the [rootBundle] is used. /// /// The image is obtained by calling [AssetBundle.load] on the given [bundle] diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index 00a4d4ac440e..23ccaa25c4cf 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -10,19 +10,22 @@ class RawPicture extends LeafRenderObjectWidget { Key key, this.matchTextDirection = false, this.textDirection, + this.allowDrawingOutsideViewBox = false, }) : super(key: key); final PictureInfo picture; final bool matchTextDirection; final TextDirection textDirection; + final bool allowDrawingOutsideViewBox; + @override RenderPicture createRenderObject(BuildContext context) { - // TODO: implement createRenderObject return new RenderPicture( picture: picture, matchTextDirection: matchTextDirection, - textDirection: textDirection); + textDirection: textDirection, + allowDrawingOutsideViewBox: allowDrawingOutsideViewBox); } @override @@ -30,7 +33,8 @@ class RawPicture extends LeafRenderObjectWidget { renderObject ..picture = picture ..matchTextDirection = matchTextDirection - ..textDirection = textDirection; + ..textDirection = textDirection + ..allowDrawingOutsideViewBox = allowDrawingOutsideViewBox; } } @@ -39,21 +43,23 @@ class RenderPicture extends RenderBox { PictureInfo picture, bool matchTextDirection: false, TextDirection textDirection, + bool allowDrawingOutsideViewBox, }) : _picture = picture, _matchTextDirection = matchTextDirection, - _textDirection = textDirection; + _textDirection = textDirection, + _allowDrawingOutsideViewBox = allowDrawingOutsideViewBox; - /// Whether to paint the image in the direction of the [TextDirection]. + /// Whether to paint the picture in the direction of the [TextDirection]. /// - /// If this is true, then in [TextDirection.ltr] contexts, the image will be + /// If this is true, then in [TextDirection.ltr] contexts, the picture will be /// drawn with its origin in the top left (the "normal" painting direction for - /// images); and in [TextDirection.rtl] contexts, the image will be drawn with + /// pictures); and in [TextDirection.rtl] contexts, the picture will be drawn with /// a scaling factor of -1 in the horizontal direction so that the origin is /// in the top right. /// - /// This is occasionally used with images in right-to-left environments, for - /// images that were designed for left-to-right locales. Be careful, when - /// using this, to not flip images with integral shadows, text, or other + /// This is occasionally used with pictures in right-to-left environments, for + /// pictures that were designed for left-to-right locales. Be careful, when + /// using this, to not flip pictures with integral shadows, text, or other /// effects that will look incorrect when flipped. /// /// If this is set to true, [textDirection] must not be null. @@ -96,6 +102,17 @@ class RenderPicture extends RenderBox { markNeedsPaint(); } + bool _allowDrawingOutsideViewBox; + bool get allowDrawingOutsideViewBox => _allowDrawingOutsideViewBox; + set allowDrawingOutsideViewBox(bool val) { + if (val == _allowDrawingOutsideViewBox) { + return; + } + + _allowDrawingOutsideViewBox = val; + markNeedsPaint(); + } + @override bool hitTestSelf(Offset position) => true; @@ -121,6 +138,7 @@ class RenderPicture extends RenderBox { } // this is sometimes useful for debugging, will remove + // creates a red border around the drawing // context.canvas.drawRect( // Offset.zero & size, // new Paint() @@ -128,7 +146,9 @@ class RenderPicture extends RenderBox { // ..style = PaintingStyle.stroke); scaleCanvasToViewBox(context.canvas, size, picture.viewBox); - context.canvas.clipRect(picture.viewBox); + if (allowDrawingOutsideViewBox != true) { + context.canvas.clipRect(picture.viewBox); + } context.canvas.drawPicture(picture.picture); context.canvas.restore(); } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 53945f06efcb..aa1709d12230 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -216,29 +216,41 @@ class Svg { class SvgPicture extends StatefulWidget { const SvgPicture(this.pictureProvider, - {Key key, this.matchTextDirection = false}) + {Key key, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false}) : super(key: key); SvgPicture.asset(String assetName, {Key key, this.matchTextDirection = false, AssetBundle bundle, - String package}) + String package, + this.allowDrawingOutsideViewBox = false}) : pictureProvider = new ExactAssetPicture(svgByteDecoder, assetName, bundle: bundle, package: package), super(key: key); SvgPicture.network(String url, - {Key key, Map headers, this.matchTextDirection = false}) + {Key key, + Map headers, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false}) : pictureProvider = new NetworkPicture(svgByteDecoder, url, headers: headers), super(key: key); - SvgPicture.file(File file, {Key key, this.matchTextDirection = false}) + SvgPicture.file(File file, + {Key key, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false}) : pictureProvider = new FilePicture(svgByteDecoder, file), super(key: key); - SvgPicture.memory(Uint8List bytes, {Key key, this.matchTextDirection = false}) + SvgPicture.memory(Uint8List bytes, + {Key key, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false}) : pictureProvider = new MemoryPicture(svgByteDecoder, bytes), super(key: key); @@ -249,6 +261,7 @@ class SvgPicture extends StatefulWidget { final PictureProvider pictureProvider; final bool matchTextDirection; + final bool allowDrawingOutsideViewBox; @override State createState() => new _SvgPictureState(); @@ -308,11 +321,6 @@ class _SvgPictureState extends State { if (_isListeningToStream) _pictureStream.removeListener(_handleImageChanged); - // if (!widget.gaplessPlayback) - // setState(() { - // _imageInfo = null; - // }); - _pictureStream = newStream; if (_isListeningToStream) { _pictureStream.addListener(_handleImageChanged); @@ -347,6 +355,7 @@ class _SvgPictureState extends State { return new RawPicture( _picture, matchTextDirection: widget.matchTextDirection, + allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, ); } From b2255b0d7cbda07a41a0830d9269fa0404ee7e16 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 26 May 2018 23:07:37 -0400 Subject: [PATCH 086/512] update PictureConfiguration --- third_party/lib/src/picture_cache.dart | 8 +++- third_party/lib/src/picture_provider.dart | 51 +++++++++++++++-------- third_party/lib/svg.dart | 3 +- third_party/pubspec.lock | 15 ++----- 4 files changed, 45 insertions(+), 32 deletions(-) diff --git a/third_party/lib/src/picture_cache.dart b/third_party/lib/src/picture_cache.dart index 88cc2c18b2a1..06e8e6c3ea42 100644 --- a/third_party/lib/src/picture_cache.dart +++ b/third_party/lib/src/picture_cache.dart @@ -23,12 +23,16 @@ class PictureCache { set maximumSize(int value) { assert(value != null); assert(value >= 0); - if (value == maximumSize) return; + if (value == maximumSize) { + return; + } _maximumSize = value; if (maximumSize == 0) { _cache.clear(); } else { - while (_cache.length > maximumSize) _cache.remove(_cache.keys.first); + while (_cache.length > maximumSize) { + _cache.remove(_cache.keys.first); + } } } diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 10825cb3e70e..94c091b1efa7 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -5,16 +5,48 @@ import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; -import 'dart:ui' show Rect, Locale, TextDirection, hashValues; +import 'dart:ui' show Rect, Locale, TextDirection, hashValues, Size; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart' + show + BuildContext, + DefaultAssetBundle, + Directionality, + Localizations, + MediaQuery; import 'picture_cache.dart'; import 'picture_stream.dart'; typedef FutureOr PictureInfoDecoder(T data); +/// Creates an [ImageConfiguration] based on the given [BuildContext] (and +/// optionally size). +/// +/// This is the object that must be passed to [BoxPainter.paint] and to +/// [ImageProvider.resolve]. +/// +/// If this is not called from a build method, then it should be reinvoked +/// whenever the dependencies change, e.g. by calling it from +/// [State.didChangeDependencies], so that any changes in the environment are +/// picked up (e.g. if the device pixel ratio changes). +/// +/// See also: +/// +/// * [ImageProvider], which has an example showing how this might be used. +PictureConfiguration createLocalPictureConfiguration(BuildContext context, + {Rect viewBox}) { + return new PictureConfiguration( + bundle: DefaultAssetBundle.of(context), + locale: Localizations.localeOf(context, nullOk: true), + textDirection: Directionality.of(context), + viewBox: viewBox, + platform: defaultTargetPlatform, + ); +} + /// Configuration information passed to the [PictureProvider.resolve] method to /// select a specific image. /// @@ -32,7 +64,6 @@ class PictureConfiguration { /// advisory and best-effort. const PictureConfiguration({ this.bundle, - this.devicePixelRatio, this.locale, this.textDirection, this.viewBox, @@ -45,7 +76,6 @@ class PictureConfiguration { /// advisory and best-effort. PictureConfiguration copyWith({ AssetBundle bundle, - double devicePixelRatio, Locale locale, TextDirection textDirection, Rect viewBox, @@ -53,7 +83,6 @@ class PictureConfiguration { }) { return new PictureConfiguration( bundle: bundle ?? this.bundle, - devicePixelRatio: devicePixelRatio ?? this.devicePixelRatio, locale: locale ?? this.locale, textDirection: textDirection ?? this.textDirection, viewBox: viewBox ?? this.viewBox, @@ -65,9 +94,6 @@ class PictureConfiguration { /// does not have one already selected. final AssetBundle bundle; - /// The device pixel ratio where the image will be shown. - final double devicePixelRatio; - /// The language and region for which to select the image. final Locale locale; @@ -95,7 +121,6 @@ class PictureConfiguration { } final PictureConfiguration typedOther = other; return typedOther.bundle == bundle && - typedOther.devicePixelRatio == devicePixelRatio && typedOther.locale == locale && typedOther.textDirection == textDirection && typedOther.viewBox == viewBox && @@ -103,8 +128,7 @@ class PictureConfiguration { } @override - int get hashCode => - hashValues(bundle, devicePixelRatio, locale, viewBox, platform); + int get hashCode => hashValues(bundle, locale, viewBox, platform); @override String toString() { @@ -118,13 +142,6 @@ class PictureConfiguration { result.write('bundle: $bundle'); hasArguments = true; } - if (devicePixelRatio != null) { - if (hasArguments) { - result.write(', '); - } - result.write('devicePixelRatio: ${devicePixelRatio.toStringAsFixed(1)}'); - hasArguments = true; - } if (locale != null) { if (hasArguments) { result.write(', '); diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index aa1709d12230..68ffafef4514 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -299,7 +299,8 @@ class _SvgPictureState extends State { } void _resolveImage() { - final PictureStream newStream = widget.pictureProvider.resolve(null); + final PictureStream newStream = widget.pictureProvider + .resolve(createLocalPictureConfiguration(context)); assert(newStream != null); _updateSourceStream(newStream); } diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 66fa45a4c95d..d6a60768cbb9 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -278,18 +278,9 @@ packages: source: hosted version: "0.2.2" sky_engine: - dependency: "direct overridden" - description: - path: "/Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_engine" - relative: false - source: path - version: "0.0.99" - sky_services: - dependency: "direct overridden" - description: - path: "/Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_services" - relative: false - source: path + dependency: transitive + description: flutter + source: sdk version: "0.0.99" source_map_stack_trace: dependency: transitive From 8ed43e1245d91a5ba39948cafd58b6e9f717083c Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 26 May 2018 23:25:06 -0400 Subject: [PATCH 087/512] allow drawing outside viewbox on picture --- third_party/lib/src/picture_provider.dart | 9 +--- third_party/lib/src/vector_drawable.dart | 11 +++- third_party/lib/svg.dart | 62 ++++++++++++++++++----- third_party/test/widget_svg_test.dart | 14 ++++- 4 files changed, 73 insertions(+), 23 deletions(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 94c091b1efa7..2c589c0bc21c 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -5,17 +5,12 @@ import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; -import 'dart:ui' show Rect, Locale, TextDirection, hashValues, Size; +import 'dart:ui' show Rect, Locale, TextDirection, hashValues; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart' - show - BuildContext, - DefaultAssetBundle, - Directionality, - Localizations, - MediaQuery; + show BuildContext, DefaultAssetBundle, Directionality, Localizations; import 'picture_cache.dart'; import 'picture_stream.dart'; diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 6b88bc807dc0..b2f27763aa69 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -255,7 +255,12 @@ class DrawableRoot implements Drawable { } } - Picture toPicture({Size size}) { + /// Creates a [Picture] from this [DrawableRoot]. + /// + /// Be cautious about not clipping to the ViewBox - you will be + /// allowing your drawing to take more memory than it otherwise would, + /// particularly when it is eventually rasterized. + Picture toPicture({Size size, bool clipToViewBox = true}) { if (viewBox == null || viewBox.size.width == 0) { return null; } @@ -266,7 +271,9 @@ class DrawableRoot implements Drawable { if (size != null) { scaleCanvasToViewBox(canvas, size); } - clipCanvasToViewBox(canvas); + if (clipToViewBox == true) { + clipCanvasToViewBox(canvas); + } draw(canvas); canvas.restore(); diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 68ffafef4514..ed0ccf184f72 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -112,15 +112,21 @@ final Svg svg = new Svg._(); class Svg { Svg._(); - FutureOr svgPictureDecoder(Uint8List raw) async { + FutureOr svgPictureDecoder( + Uint8List raw, bool allowDrawingOutsideOfViewBox) async { final DrawableRoot svgRoot = await fromSvgBytes(raw); - final Picture pic = svgRoot.toPicture(); + final Picture pic = svgRoot.toPicture( + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true); return new PictureInfo(picture: pic, viewBox: svgRoot.viewBox); } - FutureOr svgPictureStringDecoder(String raw) { + FutureOr svgPictureStringDecoder( + String raw, bool allowDrawingOutsideOfViewBox) { final DrawableRoot svg = fromSvgString(raw); - return new PictureInfo(picture: svg.toPicture(), viewBox: svg.viewBox); + return new PictureInfo( + picture: svg.toPicture( + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true), + viewBox: svg.viewBox); } FutureOr fromSvgBytes(Uint8List raw) async { @@ -227,8 +233,13 @@ class SvgPicture extends StatefulWidget { AssetBundle bundle, String package, this.allowDrawingOutsideViewBox = false}) - : pictureProvider = new ExactAssetPicture(svgByteDecoder, assetName, - bundle: bundle, package: package), + : pictureProvider = new ExactAssetPicture( + allowDrawingOutsideViewBox == true + ? svgByteDecoderOutsideViewBox + : svgByteDecoder, + assetName, + bundle: bundle, + package: package), super(key: key); SvgPicture.network(String url, @@ -236,28 +247,55 @@ class SvgPicture extends StatefulWidget { Map headers, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false}) - : pictureProvider = - new NetworkPicture(svgByteDecoder, url, headers: headers), + : pictureProvider = new NetworkPicture( + allowDrawingOutsideViewBox == true + ? svgByteDecoderOutsideViewBox + : svgByteDecoder, + url, + headers: headers), super(key: key); SvgPicture.file(File file, {Key key, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false}) - : pictureProvider = new FilePicture(svgByteDecoder, file), + : pictureProvider = new FilePicture( + allowDrawingOutsideViewBox == true + ? svgByteDecoderOutsideViewBox + : svgByteDecoder, + file), super(key: key); SvgPicture.memory(Uint8List bytes, {Key key, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false}) - : pictureProvider = new MemoryPicture(svgByteDecoder, bytes), + : pictureProvider = new MemoryPicture( + allowDrawingOutsideViewBox == true + ? svgByteDecoderOutsideViewBox + : svgByteDecoder, + bytes), + super(key: key); + + SvgPicture.string(String bytes, + {Key key, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false}) + : pictureProvider = new StringPicture( + allowDrawingOutsideViewBox == true + ? svgStringDecoderOutsideViewBox + : svgStringDecoder, + bytes), super(key: key); static final PictureInfoDecoder svgByteDecoder = - (Uint8List bytes) => svg.svgPictureDecoder(bytes); + (Uint8List bytes) => svg.svgPictureDecoder(bytes, false); static final PictureInfoDecoder svgStringDecoder = - (String bytes) => svg.svgPictureStringDecoder(bytes); + (String data) => svg.svgPictureStringDecoder(data, false); + static final PictureInfoDecoder svgByteDecoderOutsideViewBox = + (Uint8List bytes) => svg.svgPictureDecoder(bytes, true); + static final PictureInfoDecoder svgStringDecoderOutsideViewBox = + (String data) => svg.svgPictureStringDecoder(data, true); final PictureProvider pictureProvider; final bool matchTextDirection; diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index f71984e8ac55..8241a68bf8fa 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -10,7 +10,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:mockito/mockito.dart'; void main() { - final Uint8List svg = utf8.encode(''' + final String svgStr = ''' -'''); +'''; + final Uint8List svg = utf8.encode(svgStr); + + testWidgets('SvgPicture.string', (WidgetTester tester) async { + final GlobalKey key = new GlobalKey(); + await tester.pumpWidget(new SvgPicture.string( + svgStr, + key: key, + )); + expect(find.byKey(key), findsOneWidget); + }); testWidgets('SvgPicture.memory', (WidgetTester tester) async { final GlobalKey key = new GlobalKey(); From 4516446dfbf45e953eaf315e6a616346734179c7 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 26 May 2018 23:29:06 -0400 Subject: [PATCH 088/512] pref const --- third_party/test/widget_svg_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 8241a68bf8fa..b1d1fedf2a7d 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -10,7 +10,7 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:mockito/mockito.dart'; void main() { - final String svgStr = ''' + const String svgStr = ''' Date: Sun, 27 May 2018 00:21:44 -0400 Subject: [PATCH 089/512] update readme, changelog --- third_party/CHANGELOG.md | 18 +++++++++++ third_party/example/main.dart | 16 +++++----- third_party/lib/src/picture_provider.dart | 7 ++--- third_party/lib/src/picture_stream.dart | 8 ++--- third_party/lib/src/vector_drawable.dart | 2 +- third_party/lib/svg.dart | 37 ++++++++++++++++------- 6 files changed, 60 insertions(+), 28 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index b910e4ab4030..346aa7032127 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,23 @@ # CHANGES +## 0.3.0 + +- BREAKING CHANGE: `SvgImage`, `AvdImage`, and `VectorDrawableImage` have been + deprecated. They relied on methods that are less efficient than those + now surfaced in `SvgPicture`. +- BREAKING CHANGE: Size is no longer passed to `SvgPicture` - its size is + determined by parent size. +- BREAKING CHANGE: `clipToViewBox` is now called `allowDrawingOutsideViewBox`. + It defaults to false. It should not ordinarily be set to true, as it can allow + unexpected memory usage if your vector graphic tries to draw far outside of + the viewBox bounds. +- BREAKING CHANGE: `SvgPicture` does not support custom `ErrorWidgetBuilder`s at + this point in time. However, errors will be properly logged to the console. + This is a result of improvements in the loading/caching of drawings. +- New method on DrawableRoot toPicture to create a ui.Picture object from the SVG. +- Support for caching of Pictures, similar to how framework caches images. This will + eventually be configurable, but is not as of this release. + ## 0.2.0 - Fix bug(s) in inheritence (better rendering of Ghostscript_Tiger.svg) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index f66efd287ea3..32287f3dafe9 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -3,7 +3,7 @@ import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; const List assetNames = const [ - // 'assets/notfound.svg', + 'assets/notfound.svg', 'assets/flutter_logo.svg', 'assets/dart.svg', 'assets/simple/clip_path_3.svg', @@ -36,9 +36,9 @@ const List assetNames = const [ ]; const List uriNames = const [ - // 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - // 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', - // 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', + 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', + 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', ]; void main() => runApp(new MyApp()); @@ -83,7 +83,7 @@ class _MyHomePageState extends State { @override void initState() { super.initState(); - _dimension = 250.0; + _dimension = 80.0; for (String assetName in assetNames) { _painters.add( @@ -95,9 +95,9 @@ class _MyHomePageState extends State { _painters.add( new SvgPicture.network( uriName, - // loadingPlaceholderBuilder: (BuildContext context) => new Container( - // padding: const EdgeInsets.all(30.0), - // child: const CircularProgressIndicator()), + placeholderBuilder: (BuildContext context) => new Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator()), ), ); } diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 2c589c0bc21c..d6e7d812db68 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -17,11 +17,10 @@ import 'picture_stream.dart'; typedef FutureOr PictureInfoDecoder(T data); -/// Creates an [ImageConfiguration] based on the given [BuildContext] (and +/// Creates an [PictureConfiguration] based on the given [BuildContext] (and /// optionally size). /// -/// This is the object that must be passed to [BoxPainter.paint] and to -/// [ImageProvider.resolve]. +/// This is the object that must be passed to [PictureProvider.resolve]. /// /// If this is not called from a build method, then it should be reinvoked /// whenever the dependencies change, e.g. by calling it from @@ -30,7 +29,7 @@ typedef FutureOr PictureInfoDecoder(T data); /// /// See also: /// -/// * [ImageProvider], which has an example showing how this might be used. +/// * [PictureProvider], which has an example showing how this might be used. PictureConfiguration createLocalPictureConfiguration(BuildContext context, {Rect viewBox}) { return new PictureConfiguration( diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart index 877b8be21724..2234bbb56c22 100644 --- a/third_party/lib/src/picture_stream.dart +++ b/third_party/lib/src/picture_stream.dart @@ -239,7 +239,7 @@ abstract class PictureStreamCompleter extends Diagnosticable { } } -/// Manages the loading of [dart:ui.Image] objects for static [PictureStream]s (those +/// Manages the loading of [dart:ui.Picture] objects for static [PictureStream]s (those /// with only one frame). class OneFramePictureStreamCompleter extends PictureStreamCompleter { /// Creates a manager for one-frame [PictureStream]s. @@ -256,10 +256,10 @@ class OneFramePictureStreamCompleter extends PictureStreamCompleter { /// argument on [FlutterErrorDetails] set to true, meaning that by default the /// message is only dumped to the console in debug mode (see [new /// FlutterErrorDetails]). - OneFramePictureStreamCompleter(Future image, + OneFramePictureStreamCompleter(Future picture, {InformationCollector informationCollector}) - : assert(image != null) { - image.then(setImage, onError: (dynamic error, StackTrace stack) { + : assert(picture != null) { + picture.then(setImage, onError: (dynamic error, StackTrace stack) { FlutterError.reportError(new FlutterErrorDetails( exception: error, stack: stack, diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index b2f27763aa69..a9dd2817a374 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -256,7 +256,7 @@ class DrawableRoot implements Drawable { } /// Creates a [Picture] from this [DrawableRoot]. - /// + /// /// Be cautious about not clipping to the ViewBox - you will be /// allowing your drawing to take more memory than it otherwise would, /// particularly when it is eventually rasterized. diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index ed0ccf184f72..cebad5f50a73 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -221,10 +221,14 @@ class Svg { } class SvgPicture extends StatefulWidget { + static WidgetBuilder defaultPlaceholderBuilder = + (BuildContext ctx) => const LimitedBox(); + const SvgPicture(this.pictureProvider, {Key key, this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false}) + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder}) : super(key: key); SvgPicture.asset(String assetName, @@ -232,7 +236,8 @@ class SvgPicture extends StatefulWidget { this.matchTextDirection = false, AssetBundle bundle, String package, - this.allowDrawingOutsideViewBox = false}) + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder}) : pictureProvider = new ExactAssetPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox @@ -246,7 +251,8 @@ class SvgPicture extends StatefulWidget { {Key key, Map headers, this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false}) + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder}) : pictureProvider = new NetworkPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox @@ -258,7 +264,8 @@ class SvgPicture extends StatefulWidget { SvgPicture.file(File file, {Key key, this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false}) + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder}) : pictureProvider = new FilePicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox @@ -269,7 +276,8 @@ class SvgPicture extends StatefulWidget { SvgPicture.memory(Uint8List bytes, {Key key, this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false}) + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder}) : pictureProvider = new MemoryPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox @@ -280,7 +288,8 @@ class SvgPicture extends StatefulWidget { SvgPicture.string(String bytes, {Key key, this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false}) + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder}) : pictureProvider = new StringPicture( allowDrawingOutsideViewBox == true ? svgStringDecoderOutsideViewBox @@ -298,6 +307,7 @@ class SvgPicture extends StatefulWidget { (String data) => svg.svgPictureStringDecoder(data, true); final PictureProvider pictureProvider; + final WidgetBuilder placeholderBuilder; final bool matchTextDirection; final bool allowDrawingOutsideViewBox; @@ -391,11 +401,16 @@ class _SvgPictureState extends State { @override Widget build(BuildContext context) { - return new RawPicture( - _picture, - matchTextDirection: widget.matchTextDirection, - allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, - ); + if (_picture != null) { + return new RawPicture( + _picture, + matchTextDirection: widget.matchTextDirection, + allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, + ); + } + return widget.placeholderBuilder == null + ? SvgPicture.defaultPlaceholderBuilder(context) + : widget.placeholderBuilder(context); } @override From 1bc3e2613b211af1734957d6fae8279f5a9fcebd Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 27 May 2018 00:22:31 -0400 Subject: [PATCH 090/512] bump ver --- third_party/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 3b57193361c9..107fc511b5dc 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.2.0 +version: 0.3.0 dependencies: path_drawing: ^0.2.3 From 9722f7d5024885e6dcce39060250ce55696336a4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 27 May 2018 00:26:40 -0400 Subject: [PATCH 091/512] update changelog --- third_party/CHANGELOG.md | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 346aa7032127..067e498e7de9 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -2,6 +2,14 @@ ## 0.3.0 +- This version represents a major rewrite of the widget(s) involved in rendering + SVG drawings. This is primarily to support caching and better performance in rendering. +- New method on DrawableRoot toPicture to create a ui.Picture object from the SVG. +- Support for caching of Pictures, similar to how framework caches images. This will + eventually be configurable, but is not as of this release. + +### BREAKING CHANGES + - BREAKING CHANGE: `SvgImage`, `AvdImage`, and `VectorDrawableImage` have been deprecated. They relied on methods that are less efficient than those now surfaced in `SvgPicture`. @@ -14,9 +22,6 @@ - BREAKING CHANGE: `SvgPicture` does not support custom `ErrorWidgetBuilder`s at this point in time. However, errors will be properly logged to the console. This is a result of improvements in the loading/caching of drawings. -- New method on DrawableRoot toPicture to create a ui.Picture object from the SVG. -- Support for caching of Pictures, similar to how framework caches images. This will - eventually be configurable, but is not as of this release. ## 0.2.0 From 69ca4bb07b5e18b882c2087777766da4aa59ce52 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 27 May 2018 15:21:51 -0400 Subject: [PATCH 092/512] color filtering! --- third_party/example/main.dart | 24 ++- third_party/lib/src/picture_provider.dart | 224 +++++++++++++--------- third_party/lib/src/render_picture.dart | 10 + third_party/lib/src/vector_drawable.dart | 26 ++- third_party/lib/src/vector_painter.dart | 2 +- third_party/lib/svg.dart | 64 +++++-- third_party/tool/gen_golden.dart | 2 +- 7 files changed, 228 insertions(+), 124 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 32287f3dafe9..16461dd04a69 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -3,7 +3,7 @@ import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; const List assetNames = const [ - 'assets/notfound.svg', + // 'assets/notfound.svg', 'assets/flutter_logo.svg', 'assets/dart.svg', 'assets/simple/clip_path_3.svg', @@ -18,6 +18,14 @@ const List assetNames = const [ 'assets/simple/style_attr.svg', 'assets/w3samples/aa.svg', 'assets/w3samples/alphachannel.svg', + 'assets/simple/ellipse.svg', + 'assets/simple/dash_path.svg', + 'assets/simple/nested_group.svg', + 'assets/wikimedia/chess_knight.svg', + 'assets/wikimedia/Ghostscript_Tiger.svg', +]; + +const List iconNames = const [ 'assets/deborah_ufw/new-action-expander.svg', 'assets/deborah_ufw/new-camera.svg', 'assets/deborah_ufw/new-gif-button.svg', @@ -28,11 +36,6 @@ const List assetNames = const [ 'assets/deborah_ufw/new-play-button.svg', 'assets/deborah_ufw/new-send-circle.svg', 'assets/deborah_ufw/numeric_25.svg', - 'assets/simple/ellipse.svg', - 'assets/simple/dash_path.svg', - 'assets/simple/nested_group.svg', - 'assets/wikimedia/chess_knight.svg', - 'assets/wikimedia/Ghostscript_Tiger.svg', ]; const List uriNames = const [ @@ -91,6 +94,15 @@ class _MyHomePageState extends State { ); } + for (int i = 0; i < iconNames.length; i++) { + _painters.add( + new SvgPicture.asset( + iconNames[i], + color: Colors.blueGrey[(i + 1) * 100], + ), + ); + } + for (String uriName in uriNames) { _painters.add( new SvgPicture.network( diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index d6e7d812db68..881ab954e679 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -5,7 +5,8 @@ import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; -import 'dart:ui' show Rect, Locale, TextDirection, hashValues; +import 'dart:ui' + show BlendMode, Color, ColorFilter, Locale, Rect, TextDirection, hashValues; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; @@ -15,7 +16,8 @@ import 'package:flutter/widgets.dart' import 'picture_cache.dart'; import 'picture_stream.dart'; -typedef FutureOr PictureInfoDecoder(T data); +typedef FutureOr PictureInfoDecoder( + T data, ColorFilter colorFilter); /// Creates an [PictureConfiguration] based on the given [BuildContext] (and /// optionally size). @@ -31,25 +33,26 @@ typedef FutureOr PictureInfoDecoder(T data); /// /// * [PictureProvider], which has an example showing how this might be used. PictureConfiguration createLocalPictureConfiguration(BuildContext context, - {Rect viewBox}) { + {Rect viewBox, Color color, BlendMode colorBlendMode}) { return new PictureConfiguration( bundle: DefaultAssetBundle.of(context), locale: Localizations.localeOf(context, nullOk: true), textDirection: Directionality.of(context), viewBox: viewBox, platform: defaultTargetPlatform, + colorFilter: ColorFilter.mode(color, colorBlendMode ?? BlendMode.srcIn), ); } /// Configuration information passed to the [PictureProvider.resolve] method to -/// select a specific image. +/// select a specific picture. /// /// See also: /// /// * [createLocalPictureConfiguration], which creates an [PictureConfiguration] /// based on ambient configuration in a [Widget] environment. /// * [PictureProvider], which uses [PictureConfiguration] objects to determine -/// which image to obtain. +/// which picture to obtain. @immutable class PictureConfiguration { /// Creates an object holding the configuration information for an [PictureProvider]. @@ -62,6 +65,7 @@ class PictureConfiguration { this.textDirection, this.viewBox, this.platform, + this.colorFilter, }); /// Creates an object holding the configuration information for an [PictureProvider]. @@ -74,6 +78,7 @@ class PictureConfiguration { TextDirection textDirection, Rect viewBox, String platform, + ColorFilter colorFilter, }) { return new PictureConfiguration( bundle: bundle ?? this.bundle, @@ -81,6 +86,7 @@ class PictureConfiguration { textDirection: textDirection ?? this.textDirection, viewBox: viewBox ?? this.viewBox, platform: platform ?? this.platform, + colorFilter: colorFilter ?? this.colorFilter, ); } @@ -88,21 +94,24 @@ class PictureConfiguration { /// does not have one already selected. final AssetBundle bundle; - /// The language and region for which to select the image. + /// The language and region for which to select the picture. final Locale locale; - /// The reading direction of the language for which to select the image. + /// The reading direction of the language for which to select the picture. final TextDirection textDirection; - /// The size at which the image will be rendered. + /// The size at which the picture will be rendered. final Rect viewBox; - /// The [TargetPlatform] for which assets should be used. This allows images + /// The [TargetPlatform] for which assets should be used. This allows pictures /// to be specified in a platform-neutral fashion yet use different assets on /// different platforms, to match local conventions e.g. for color matching or /// shadows. final TargetPlatform platform; + /// The [ColorFilter], if any, that was applied to the drawing. + final ColorFilter colorFilter; + /// a picture configuration that provides no additional information. /// /// Useful when resolving an [PictureProvider] without any context. @@ -118,11 +127,13 @@ class PictureConfiguration { typedOther.locale == locale && typedOther.textDirection == textDirection && typedOther.viewBox == viewBox && - typedOther.platform == platform; + typedOther.platform == platform && + typedOther.colorFilter == colorFilter; } @override - int get hashCode => hashValues(bundle, locale, viewBox, platform); + int get hashCode => + hashValues(bundle, locale, viewBox, platform, colorFilter); @override String toString() { @@ -164,24 +175,32 @@ class PictureConfiguration { result.write('platform: ${describeEnum(platform)}'); hasArguments = true; } + if (colorFilter != null) { + if (hasArguments) { + result.write(', '); + } + result.write('colorFilter: $colorFilter'); + hasArguments = true; + } result.write(')'); return result.toString(); } } +// TODO: allow other people to implement this. PictureCache _cache = new PictureCache(); /// Identifies a picture without committing to the precise final asset. This -/// allows a set of images to be identified and for the precise image to later +/// allows a set of pictures to be identified and for the precise picture to later /// be resolved based on the environment, e.g. the device pixel ratio. /// /// To obtain an [PictureStream] from an [PictureProvider], call [resolve], /// passing it an [PictureConfiguration] object. /// -/// [PictureProvider] uses the global [imageCache] to cache images. +/// [PictureProvider] uses the global [pictureCache] to cache pictures. /// /// The type argument `T` is the type of the object used to represent a resolved -/// configuration. This is also the type used for the key in the image cache. It +/// configuration. This is also the type used for the key in the picture cache. It /// should be immutable and implement the [==] operator and the [hashCode] /// getter. Subclasses should subclass a variant of [PictureProvider] with an /// explicit `T` type argument. @@ -189,17 +208,17 @@ PictureCache _cache = new PictureCache(); /// The type argument does not have to be specified when using the type as an /// argument (where any Picture provider is acceptable). /// -/// The following image formats are supported: {@macro flutter.dart:ui.imageFormats} +/// The following picture formats are supported: {@macro flutter.dart:ui.pictureFormats} /// /// ## Sample code /// /// The following shows the code required to write a widget that fully conforms /// to the [PictureProvider] and [Widget] protocols. (It is essentially a -/// bare-bones version of the [widgets.Image] widget.) +/// bare-bones version of the [widgets.Picture] widget.) /// /// ```dart -/// class MyImage extends StatefulWidget { -/// const MyImage({ +/// class MyPicture extends StatefulWidget { +/// const MyPicture({ /// Key key, /// @required this.PictureProvider, /// }) : assert(PictureProvider != null), @@ -208,59 +227,59 @@ PictureCache _cache = new PictureCache(); /// final PictureProvider PictureProvider; /// /// @override -/// _MyImageState createState() => new _MyImageState(); +/// _MyPictureState createState() => new _MyPictureState(); /// } /// -/// class _MyImageState extends State { +/// class _MyPictureState extends State { /// PictureStream _PictureStream; -/// ImageInfo _imageInfo; +/// PictureInfo _pictureInfo; /// /// @override /// void didChangeDependencies() { /// super.didChangeDependencies(); -/// // We call _getImage here because createLocalPictureConfiguration() needs to +/// // We call _getPicture here because createLocalPictureConfiguration() needs to /// // be called again if the dependencies changed, in case the changes relate /// // to the DefaultAssetBundle, MediaQuery, etc, which that method uses. -/// _getImage(); +/// _getPicture(); /// } /// /// @override -/// void didUpdateWidget(MyImage oldWidget) { +/// void didUpdateWidget(MyPicture oldWidget) { /// super.didUpdateWidget(oldWidget); /// if (widget.PictureProvider != oldWidget.PictureProvider) -/// _getImage(); +/// _getPicture(); /// } /// -/// void _getImage() { +/// void _getPicture() { /// final PictureStream oldPictureStream = _PictureStream; /// _PictureStream = widget.PictureProvider.resolve(createLocalPictureConfiguration(context)); /// if (_PictureStream.key != oldPictureStream?.key) { -/// // If the keys are the same, then we got the same image back, and so we don't +/// // If the keys are the same, then we got the same picture back, and so we don't /// // need to update the listeners. If the key changed, though, we must make sure -/// // to switch our listeners to the new image stream. -/// oldPictureStream?.removeListener(_updateImage); -/// _PictureStream.addListener(_updateImage); +/// // to switch our listeners to the new picture stream. +/// oldPictureStream?.removeListener(_updatePicture); +/// _PictureStream.addListener(_updatePicture); /// } /// } /// -/// void _updateImage(ImageInfo imageInfo, bool synchronousCall) { +/// void _updatePicture(PictureInfo pictureInfo, bool synchronousCall) { /// setState(() { -/// // Trigger a build whenever the image changes. -/// _imageInfo = imageInfo; +/// // Trigger a build whenever the picture changes. +/// _pictureInfo = pictureInfo; /// }); /// } /// /// @override /// void dispose() { -/// _PictureStream.removeListener(_updateImage); +/// _PictureStream.removeListener(_updatePicture); /// super.dispose(); /// } /// /// @override /// Widget build(BuildContext context) { -/// return new RawImage( -/// image: _imageInfo?.image, // this is a dart:ui Image object -/// scale: _imageInfo?.scale ?? 1.0, +/// return new RawPicture( +/// picture: _pictureInfo?.picture, // this is a dart:ui Picture object +/// scale: _pictureInfo?.scale ?? 1.0, /// ); /// } /// } @@ -285,7 +304,7 @@ abstract class PictureProvider { obtainKey().then((T key) { obtainedKey = key; //stream.setCompleter(load(key)); - // stream.setCompleter(PaintingBinding.instance.imageCache + // stream.setCompleter(PaintingBinding.instance.pictureCache stream.setCompleter(_cache.putIfAbsent(key, () => load(key))); }).catchError((dynamic exception, StackTrace stack) async { FlutterError.reportError(new FlutterErrorDetails( @@ -305,10 +324,10 @@ abstract class PictureProvider { } /// Converts a pictureProvider's settings plus a pictureConfiguration to a key - /// that describes the precise image to load. + /// that describes the precise picture to load. /// /// The type of the key is determined by the subclass. It is a value that - /// unambiguously identifies the image (_including its scale_) that the [load] + /// unambiguously identifies the picture (_including its scale_) that the [load] /// method will fetch. Different [PictureProvider]s given the same constructor /// arguments and [PictureConfiguration] objects should return keys that are /// '==' to each other (possibly by using a class for the key that itself @@ -317,7 +336,7 @@ abstract class PictureProvider { Future obtainKey(); /// Converts a key into an [PictureStreamCompleter], and begins fetching the - /// image. + /// picture. @protected PictureStreamCompleter load(T key); @@ -325,21 +344,22 @@ abstract class PictureProvider { String toString() => '$runtimeType()'; } -/// Key for the image obtained by an [AssetImage] or [ExactAssetImage]. +/// Key for the picture obtained by an [AssetPicture] or [ExactAssetPicture]. /// -/// This is used to identify the precise resource in the [imageCache]. +/// This is used to identify the precise resource in the [pictureCache]. @immutable class AssetBundlePictureKey { /// Creates the key for an [AssetPicture] or [AssetBundlePictureProvider]. /// /// The arguments must not be null. - const AssetBundlePictureKey({@required this.bundle, @required this.name}) + const AssetBundlePictureKey( + {@required this.bundle, @required this.name, this.colorFilter}) : assert(bundle != null), assert(name != null); - /// The bundle from which the image will be obtained. + /// The bundle from which the picture will be obtained. /// - /// The image is obtained by calling [AssetBundle.load] on the given [bundle] + /// The picture is obtained by calling [AssetBundle.load] on the given [bundle] /// using the key given by [name]. final AssetBundle bundle; @@ -347,6 +367,9 @@ class AssetBundlePictureKey { /// argument passed to [AssetBundle.load]. final String name; + /// The [ColorFilter], if any, to be applied to the drawing. + final ColorFilter colorFilter; + @override bool operator ==(dynamic other) { if (other.runtimeType != runtimeType) { @@ -376,7 +399,7 @@ abstract class AssetBundlePictureProvider final PictureInfoDecoder decoder; /// Converts a key into an [PictureStreamCompleter], and begins fetching the - /// image using [_loadAsync]. + /// picture using [_loadAsync]. @override PictureStreamCompleter load(AssetBundlePictureKey key) { return new OneFramePictureStreamCompleter(_loadAsync(key), @@ -386,8 +409,8 @@ abstract class AssetBundlePictureProvider }); } - /// Fetches the image from the asset bundle, decodes it, and returns a - /// corresponding [ImageInfo] object. + /// Fetches the picture from the asset bundle, decodes it, and returns a + /// corresponding [PictureInfo] object. /// /// This function is used by [load]. @protected @@ -397,7 +420,7 @@ abstract class AssetBundlePictureProvider throw 'Unable to read data'; } - return await decoder(data.buffer.asUint8List()); + return await decoder(data.buffer.asUint8List(), key.colorFilter); } } @@ -405,29 +428,32 @@ final HttpClient _httpClient = new HttpClient(); /// Fetches the given URL from the network, associating it with the given scale. /// -/// The image will be cached regardless of cache headers from the server. +/// The picture will be cached regardless of cache headers from the server. /// /// See also: /// -/// * [Image.network] for a shorthand of an [Image] widget backed by [NetworkImage]. +/// * [SvgPicture.network] for a shorthand of an [SvgPicture] widget backed by [NetworkPicture]. // TODO(ianh): Find some way to honour cache headers to the extent that when the -// last reference to a picture is released, we proactively evict the image from -// our cache if the headers describe the image as having expired at that point. +// last reference to a picture is released, we proactively evict the picture from +// our cache if the headers describe the picture as having expired at that point. class NetworkPicture extends PictureProvider { - /// Creates an object that fetches the image at the given URL. + /// Creates an object that fetches the picture at the given URL. /// /// The arguments must not be null. - const NetworkPicture(this.decoder, this.url, {this.headers}) + const NetworkPicture(this.decoder, this.url, {this.headers, this.colorFilter}) : assert(url != null); final PictureInfoDecoder decoder; - /// The URL from which the image will be fetched. + /// The URL from which the picture will be fetched. final String url; - /// The HTTP headers that will be used with [HttpClient.get] to fetch image from network. + /// The HTTP headers that will be used with [HttpClient.get] to fetch picture from network. final Map headers; + /// The [ColorFilter], if any, to apply to the drawing. + final ColorFilter colorFilter; + @override Future obtainKey() { return new SynchronousFuture(this); @@ -453,7 +479,7 @@ class NetworkPicture extends PictureProvider { } final Uint8List bytes = await consolidateHttpClientResponseBytes(response); - return await decoder(bytes); + return await decoder(bytes, colorFilter); } @override @@ -477,20 +503,24 @@ class NetworkPicture extends PictureProvider { /// /// See also: /// -/// * [Image.file] for a shorthand of an [Image] widget backed by [FileImage]. +/// * [SvgPicture.file] for a shorthand of an [SvgPicture] widget backed by [FilePicture]. class FilePicture extends PictureProvider { /// Creates an object that decodes a [File] as a picture. /// /// The arguments must not be null. - const FilePicture(this.decoder, this.file) + const FilePicture(this.decoder, this.file, {this.colorFilter}) : assert(decoder != null), assert(file != null); /// The file to decode into a picture. final File file; + /// The [PictureInfoDecoder] to use for loading this picture. final PictureInfoDecoder decoder; + /// The [ColorFilter], if any, to use when drawing this picture. + final ColorFilter colorFilter; + @override Future obtainKey() { return new SynchronousFuture(this); @@ -512,7 +542,7 @@ class FilePicture extends PictureProvider { return null; } - return await decoder(data); + return await decoder(data, colorFilter); } @override @@ -538,7 +568,7 @@ class FilePicture extends PictureProvider { /// to a [MemoryPicture]. To provide an [PictureStream] that represents a picture /// that changes over time, consider creating a new subclass of [PictureProvider] /// whose [load] method returns a subclass of [PictureStreamCompleter] that can -/// handle providing multiple images. +/// handle providing multiple pictures. /// /// See also: /// @@ -547,10 +577,15 @@ class MemoryPicture extends PictureProvider { /// Creates an object that decodes a [Uint8List] buffer as a picture. /// /// The arguments must not be null. - const MemoryPicture(this.decoder, this.bytes) : assert(bytes != null); + const MemoryPicture(this.decoder, this.bytes, {this.colorFilter}) + : assert(bytes != null); + /// The [PictureInfoDecoder] to use when drawing this picture. final PictureInfoDecoder decoder; + /// The [ColorFilter], if any, to use when drawing this picture. + final ColorFilter colorFilter; + /// The bytes to decode into a picture. final Uint8List bytes; @@ -566,7 +601,7 @@ class MemoryPicture extends PictureProvider { Future _loadAsync(MemoryPicture key) async { assert(key == this); - return await decoder(bytes); + return await decoder(bytes, colorFilter); } @override @@ -589,10 +624,15 @@ class StringPicture extends PictureProvider { /// Creates an object that decodes a [Uint8List] buffer as a picture. /// /// The arguments must not be null. - const StringPicture(this.decoder, this.string) : assert(string != null); + const StringPicture(this.decoder, this.string, {this.colorFilter}) + : assert(string != null); + /// The [PictureInfoDecoder] to use for decoding this picture. final PictureInfoDecoder decoder; + /// The [ColorFilter], if any, to use when drawing this picture. + final ColorFilter colorFilter; + /// The string to decode into a picture. final String string; @@ -608,7 +648,7 @@ class StringPicture extends PictureProvider { Future _loadAsync(StringPicture key) async { assert(key == this); - return await decoder(string); + return await decoder(string, colorFilter); } @override @@ -632,8 +672,8 @@ class StringPicture extends PictureProvider { /// This implementation requires an explicit final [assetName] and [scale] on /// construction, and ignores the device pixel ratio and size in the /// configuration passed into [resolve]. For a resolution-aware variant that -/// uses the configuration to pick an appropriate image based on the device -/// pixel ratio and size, see [AssetImage]. +/// uses the configuration to pick an appropriate picture based on the device +/// pixel ratio and size, see [AssetPicture]. /// /// ## Fetching assets /// @@ -648,20 +688,20 @@ class StringPicture extends PictureProvider { /// - icons/heart.png /// ``` /// -/// Then, to fetch the image and associate it with scale `1.5`, use +/// Then, to fetch the picture and associate it with scale `1.5`, use /// /// ```dart -/// new AssetImage('icons/heart.png', scale: 1.5) +/// new AssetPicture('icons/heart.png', scale: 1.5) /// ``` /// ///## Assets in packages /// /// To fetch an asset from a package, the [package] argument must be provided. /// For instance, suppose the structure above is inside a package called -/// `my_icons`. Then to fetch the image, use: +/// `my_icons`. Then to fetch the picture, use: /// /// ```dart -/// new AssetImage('icons/heart.png', scale: 1.5, package: 'my_icons') +/// new AssetPicture('icons/heart.png', scale: 1.5, package: 'my_icons') /// ``` /// /// Assets used by the package itself should also be fetched using the [package] @@ -672,7 +712,7 @@ class StringPicture extends PictureProvider { /// package itself must be specified in its `pubspec.yaml`. /// /// A package can also choose to have assets in its 'lib/' folder that are not -/// specified in its `pubspec.yaml`. In this case for those images to be +/// specified in its `pubspec.yaml`. In this case for those pictures to be /// bundled, the app has to specify which ones to include. For instance a /// package named `fancy_backgrounds` could have: /// @@ -682,7 +722,7 @@ class StringPicture extends PictureProvider { /// lib/backgrounds/background3.png ///``` /// -/// To include, say the first image, the `pubspec.yaml` of the app should specify +/// To include, say the first picture, the `pubspec.yaml` of the app should specify /// it in the `assets` section: /// /// ```yaml @@ -695,10 +735,10 @@ class StringPicture extends PictureProvider { /// /// See also: /// -/// * [Image.asset] for a shorthand of an [Image] widget backed by -/// [ExactAssetImage] when using a scale. +/// * [SvgPicture.asset] for a shorthand of an [SvgPicture] widget backed by +/// [ExactAssetPicture] when using a scale. class ExactAssetPicture extends AssetBundlePictureProvider { - /// Creates an object that fetches the given image from an asset bundle. + /// Creates an object that fetches the given picture from an asset bundle. /// /// The [assetName] and [scale] arguments must not be null. The [scale] arguments /// defaults to 1.0. The [bundle] argument may be null, in which case the @@ -706,13 +746,14 @@ class ExactAssetPicture extends AssetBundlePictureProvider { /// will be used instead. /// /// The [package] argument must be non-null when fetching an asset that is - /// included in a package. See the documentation for the [ExactAssetImage] class + /// included in a package. See the documentation for the [ExactAssetPicture] class /// itself for details. const ExactAssetPicture( PictureInfoDecoder decoder, this.assetName, { this.bundle, this.package, + this.colorFilter, }) : assert(assetName != null), super(decoder); @@ -724,24 +765,30 @@ class ExactAssetPicture extends AssetBundlePictureProvider { String get keyName => package == null ? assetName : 'packages/$package/$assetName'; - /// The bundle from which the image will be obtained. + /// The [ColorFilter], if any, to use when drawing this picture. + final ColorFilter colorFilter; + + /// The bundle from which the picture will be obtained. /// /// If the provided [bundle] is null, the bundle provided in the /// [PictureConfiguration] passed to the [resolve] call will be used instead. If /// that is also null, the [rootBundle] is used. /// - /// The image is obtained by calling [AssetBundle.load] on the given [bundle] + /// The picture is obtained by calling [AssetBundle.load] on the given [bundle] /// using the key given by [keyName]. final AssetBundle bundle; - /// The name of the package from which the image is included. See the - /// documentation for the [ExactAssetImage] class itself for details. + /// The name of the package from which the picture is included. See the + /// documentation for the [ExactAssetPicture] class itself for details. final String package; @override Future obtainKey() { return new SynchronousFuture( - new AssetBundlePictureKey(bundle: bundle ?? rootBundle, name: keyName)); + new AssetBundlePictureKey( + bundle: bundle ?? rootBundle, + name: keyName, + colorFilter: colorFilter)); } @override @@ -750,12 +797,15 @@ class ExactAssetPicture extends AssetBundlePictureProvider { return false; } final ExactAssetPicture typedOther = other; - return keyName == typedOther.keyName && bundle == typedOther.bundle; + return keyName == typedOther.keyName && + bundle == typedOther.bundle && + colorFilter == typedOther.colorFilter; } @override - int get hashCode => hashValues(keyName, bundle); + int get hashCode => hashValues(keyName, bundle, colorFilter); @override - String toString() => '$runtimeType(name: "$keyName", bundle: $bundle)'; + String toString() => + '$runtimeType(name: "$keyName", bundle: $bundle, colorFilter: $colorFilter)'; } diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index 23ccaa25c4cf..c0d4abff05c3 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -38,6 +38,16 @@ class RawPicture extends LeafRenderObjectWidget { } } +/// A picture in the render tree. +/// +/// The render picture will draw based on its parents dimensions maintaining +/// its aspect ratio. +/// +/// If `matchTextDirection` is true, the picture will be flipped horizontally in +/// [TextDirection.rtl] contexts. If `allowDrawingOutsideViewBox` is true, the +/// picture will be allowed to draw beyond the constraints of its viewbox; this +/// flag should be used with care, as it may result in unexpected effects or +/// additional memory usage. class RenderPicture extends RenderBox { RenderPicture({ PictureInfo picture, diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index a9dd2817a374..96210091fc5d 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -15,7 +15,7 @@ abstract class Drawable { /// Draws the contents or children of this [Drawable] to the `canvas`, using /// the `parentPaint` to optionally override the child's paint. - void draw(Canvas canvas); + void draw(Canvas canvas, ColorFilter colorFilter); } /// Styling information for vector drawing. @@ -154,7 +154,7 @@ class DrawableText implements Drawable { bool get hasDrawableContent => _paragraph.width > 0.0; @override - void draw(Canvas canvas) { + void draw(Canvas canvas, ColorFilter colorFilter) { if (!hasDrawableContent) { return; } @@ -246,21 +246,25 @@ class DrawableRoot implements Drawable { children.isNotEmpty == true && viewBox != null && !viewBox.isEmpty; @override - void draw(Canvas canvas) { + void draw(Canvas canvas, ColorFilter colorFilter) { if (!hasDrawableContent) { return; } for (Drawable child in children) { - child.draw(canvas); + child.draw(canvas, colorFilter); } } + static CircularIntervalList bms = + new CircularIntervalList(BlendMode.values); + /// Creates a [Picture] from this [DrawableRoot]. /// /// Be cautious about not clipping to the ViewBox - you will be /// allowing your drawing to take more memory than it otherwise would, /// particularly when it is eventually rasterized. - Picture toPicture({Size size, bool clipToViewBox = true}) { + Picture toPicture( + {Size size, bool clipToViewBox = true, ColorFilter colorFilter}) { if (viewBox == null || viewBox.size.width == 0) { return null; } @@ -275,7 +279,7 @@ class DrawableRoot implements Drawable { clipCanvasToViewBox(canvas); } - draw(canvas); + draw(canvas, colorFilter); canvas.restore(); return recorder.endRecording(); } @@ -292,7 +296,7 @@ class DrawableNoop implements Drawable { bool get hasDrawableContent => false; @override - void draw(Canvas canvas) {} + void draw(Canvas canvas, ColorFilter colorFilter) {} } /// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. @@ -306,7 +310,7 @@ class DrawableGroup implements Drawable { bool get hasDrawableContent => children != null && children.isNotEmpty; @override - void draw(Canvas canvas) { + void draw(Canvas canvas, ColorFilter colorFilter) { if (!hasDrawableContent) { return; } @@ -317,7 +321,7 @@ class DrawableGroup implements Drawable { canvas.transform(style?.transform); } for (Drawable child in children) { - child.draw(canvas); + child.draw(canvas, colorFilter); } if (style?.transform != null) { canvas.restore(); @@ -365,7 +369,7 @@ class DrawableShape implements Drawable { bool get hasDrawableContent => bounds.width + bounds.height > 0; @override - void draw(Canvas canvas) { + void draw(Canvas canvas, ColorFilter colorFilter) { if (!hasDrawableContent || style == null) { return; } @@ -376,11 +380,13 @@ class DrawableShape implements Drawable { final Function innerDraw = () { if (style.fill != null && !identical(style.fill, DrawableStyle.emptyPaint)) { + style.fill.colorFilter = colorFilter; canvas.drawPath(path, style.fill); } if (style.stroke != null && !identical(style.stroke, DrawableStyle.emptyPaint)) { + style.stroke.colorFilter = colorFilter; if (style.dashArray != null && !identical(style.dashArray, DrawableStyle.emptyDashArray)) { canvas.drawPath( diff --git a/third_party/lib/src/vector_painter.dart b/third_party/lib/src/vector_painter.dart index 2926d0129d7b..74e09faab8b4 100644 --- a/third_party/lib/src/vector_painter.dart +++ b/third_party/lib/src/vector_painter.dart @@ -18,7 +18,7 @@ class VectorPainter extends CustomPainter { drawable.scaleCanvasToViewBox(canvas, size); drawable.clipCanvasToViewBox(canvas); - drawable.draw(canvas); + drawable.draw(canvas, null); } // TODO: implement semanticsBuilder diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index cebad5f50a73..9b99755d1dad 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -112,20 +112,22 @@ final Svg svg = new Svg._(); class Svg { Svg._(); - FutureOr svgPictureDecoder( - Uint8List raw, bool allowDrawingOutsideOfViewBox) async { + FutureOr svgPictureDecoder(Uint8List raw, + bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter) async { final DrawableRoot svgRoot = await fromSvgBytes(raw); final Picture pic = svgRoot.toPicture( - clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true); + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, + colorFilter: colorFilter); return new PictureInfo(picture: pic, viewBox: svgRoot.viewBox); } FutureOr svgPictureStringDecoder( - String raw, bool allowDrawingOutsideOfViewBox) { + String raw, bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter) { final DrawableRoot svg = fromSvgString(raw); return new PictureInfo( picture: svg.toPicture( - clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true), + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, + colorFilter: colorFilter), viewBox: svg.viewBox); } @@ -237,14 +239,17 @@ class SvgPicture extends StatefulWidget { AssetBundle bundle, String package, this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder}) + this.placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn}) : pictureProvider = new ExactAssetPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox : svgByteDecoder, assetName, bundle: bundle, - package: package), + package: package, + colorFilter: _getColorFilter(color, colorBlendMode)), super(key: key); SvgPicture.network(String url, @@ -252,59 +257,80 @@ class SvgPicture extends StatefulWidget { Map headers, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder}) + this.placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn}) : pictureProvider = new NetworkPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox : svgByteDecoder, url, - headers: headers), + headers: headers, + colorFilter: _getColorFilter(color, colorBlendMode)), super(key: key); SvgPicture.file(File file, {Key key, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder}) + this.placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn}) : pictureProvider = new FilePicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox : svgByteDecoder, - file), + file, + colorFilter: _getColorFilter(color, colorBlendMode)), super(key: key); SvgPicture.memory(Uint8List bytes, {Key key, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder}) + this.placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn}) : pictureProvider = new MemoryPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox : svgByteDecoder, - bytes), + bytes, + colorFilter: _getColorFilter(color, colorBlendMode)), super(key: key); SvgPicture.string(String bytes, {Key key, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder}) + this.placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn}) : pictureProvider = new StringPicture( allowDrawingOutsideViewBox == true ? svgStringDecoderOutsideViewBox : svgStringDecoder, - bytes), + bytes, + colorFilter: _getColorFilter(color, colorBlendMode)), super(key: key); + static ColorFilter _getColorFilter(Color color, BlendMode colorBlendMode) => + color == null + ? null + : new ColorFilter.mode(color, colorBlendMode ?? BlendMode.srcIn); + static final PictureInfoDecoder svgByteDecoder = - (Uint8List bytes) => svg.svgPictureDecoder(bytes, false); + (Uint8List bytes, ColorFilter colorFilter) => + svg.svgPictureDecoder(bytes, false, colorFilter); static final PictureInfoDecoder svgStringDecoder = - (String data) => svg.svgPictureStringDecoder(data, false); + (String data, ColorFilter colorFilter) => + svg.svgPictureStringDecoder(data, false, colorFilter); static final PictureInfoDecoder svgByteDecoderOutsideViewBox = - (Uint8List bytes) => svg.svgPictureDecoder(bytes, true); + (Uint8List bytes, ColorFilter colorFilter) => + svg.svgPictureDecoder(bytes, true, colorFilter); static final PictureInfoDecoder svgStringDecoderOutsideViewBox = - (String data) => svg.svgPictureStringDecoder(data, true); + (String data, ColorFilter colorFilter) => + svg.svgPictureStringDecoder(data, true, colorFilter); final PictureProvider pictureProvider; final WidgetBuilder placeholderBuilder; diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index e1c5896be0eb..aca4ef5e2c6f 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -26,7 +26,7 @@ Future getSvgPngBytes(String svgData) async { svgRoot.clipCanvasToViewBox(canvas); canvas.drawPaint(new Paint()..color = const Color(0xFFFFFFFF)); - svgRoot.draw(canvas); + svgRoot.draw(canvas, null); final Picture pict = rec.endRecording(); From d1d2193b7b215341069c9e6fb0bb99beb2f99aaa Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 28 May 2018 09:13:02 -0400 Subject: [PATCH 093/512] ver bump --- third_party/CHANGELOG.md | 5 +++++ third_party/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 067e498e7de9..e148ad93120b 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 0.3.1 + +- Support for tinting/coloring the output +- Documentation updates + ## 0.3.0 - This version represents a major rewrite of the widget(s) involved in rendering diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 107fc511b5dc..264a44d74811 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.3.0 +version: 0.3.1 dependencies: path_drawing: ^0.2.3 From 15aceff6c6a72d7014ea83f79b2306c8c568c367 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 28 May 2018 19:33:09 -0400 Subject: [PATCH 094/512] color as part of hash/equals --- third_party/example/main.dart | 2 ++ third_party/lib/src/picture_provider.dart | 36 +++++++++++++---------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 16461dd04a69..0e24452a1aa5 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -103,6 +103,8 @@ class _MyHomePageState extends State { ); } + _painters.add(new SvgPicture.asset(iconNames[0], color: Colors.red)); + for (String uriName in uriNames) { _painters.add( new SvgPicture.network( diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 881ab954e679..c76f47fd0fe1 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -303,8 +303,6 @@ abstract class PictureProvider { T obtainedKey; obtainKey().then((T key) { obtainedKey = key; - //stream.setCompleter(load(key)); - // stream.setCompleter(PaintingBinding.instance.pictureCache stream.setCompleter(_cache.putIfAbsent(key, () => load(key))); }).catchError((dynamic exception, StackTrace stack) async { FlutterError.reportError(new FlutterErrorDetails( @@ -376,14 +374,17 @@ class AssetBundlePictureKey { return false; } final AssetBundlePictureKey typedOther = other; - return bundle == typedOther.bundle && name == typedOther.name; + return bundle == typedOther.bundle && + name == typedOther.name && + colorFilter == typedOther.colorFilter; } @override - int get hashCode => hashValues(bundle, name); + int get hashCode => hashValues(bundle, name, colorFilter); @override - String toString() => '$runtimeType(bundle: $bundle, name: "$name")'; + String toString() => + '$runtimeType(bundle: $bundle, name: "$name", colorFilter: $colorFilter)'; } /// A subclass of [PictureProvider] that knows about [AssetBundle]s. @@ -488,14 +489,15 @@ class NetworkPicture extends PictureProvider { return false; } final NetworkPicture typedOther = other; - return url == typedOther.url; + return url == typedOther.url && colorFilter == typedOther.colorFilter; } @override - int get hashCode => url.hashCode; + int get hashCode => hashValues(url.hashCode, colorFilter); @override - String toString() => '$runtimeType("$url", $headers)'; + String toString() => + '$runtimeType("$url", headers: $headers, colorFilter: $colorFilter)'; } /// Decodes the given [File] object as a picture, associating it with the given @@ -551,14 +553,16 @@ class FilePicture extends PictureProvider { return false; } final FilePicture typedOther = other; - return file?.path == typedOther.file?.path; + return file?.path == typedOther.file?.path && + typedOther.colorFilter == colorFilter; } @override - int get hashCode => file?.path?.hashCode; + int get hashCode => hashValues(file?.path?.hashCode, colorFilter); @override - String toString() => '$runtimeType("${file?.path}")'; + String toString() => + '$runtimeType("${file?.path}", colorFilter: $colorFilter)'; } /// Decodes the given [String] buffer as a picture, associating it with the @@ -610,11 +614,11 @@ class MemoryPicture extends PictureProvider { return false; } final MemoryPicture typedOther = other; - return bytes == typedOther.bytes; + return bytes == typedOther.bytes && colorFilter == typedOther.colorFilter; } @override - int get hashCode => bytes.hashCode; + int get hashCode => hashValues(bytes.hashCode, colorFilter); @override String toString() => '$runtimeType(${describeIdentity(bytes)})'; @@ -657,14 +661,14 @@ class StringPicture extends PictureProvider { return false; } final StringPicture typedOther = other; - return string == typedOther.string; + return string == typedOther.string && colorFilter == typedOther.colorFilter; } @override - int get hashCode => string.hashCode; + int get hashCode => hashValues(string.hashCode, colorFilter); @override - String toString() => '$runtimeType($string)'; + String toString() => '$runtimeType($string, colorFilter: $colorFilter)'; } /// Fetches a picture from an [AssetBundle], associating it with the given scale. From d59ecbb0b286a82aef543933cfe1d4d595f84742 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 29 May 2018 07:27:08 -0400 Subject: [PATCH 095/512] bump ver --- third_party/CHANGELOG.md | 4 ++++ third_party/pubspec.lock | 2 +- third_party/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index e148ad93120b..01061ba01859 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 0.3.2 + +- Bug fix around caching for tinting/coloring (color was not being properly included in cache keys) + ## 0.3.1 - Support for tinting/coloring the output diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index d6a60768cbb9..9947aa1714e1 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -388,5 +388,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.55.0.flutter-97b6c2e09d" + dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.58.0.flutter-f981f09760" flutter: ">=0.3.6 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 264a44d74811..5b752bf45954 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.3.1 +version: 0.3.2 dependencies: path_drawing: ^0.2.3 From b045546933ae566eb56ab89fa383b84618c3005c Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Thu, 7 Jun 2018 16:44:31 +0200 Subject: [PATCH 096/512] fixed centering of image in scaleCanvasToViewBox() --- third_party/lib/src/render_picture.dart | 21 +++++++-------------- third_party/lib/src/vector_drawable.dart | 19 ++++--------------- 2 files changed, 11 insertions(+), 29 deletions(-) diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index c0d4abff05c3..29f741a10e44 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -1,3 +1,5 @@ +import 'dart:math' as math; + import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart'; @@ -165,18 +167,9 @@ class RenderPicture extends RenderBox { } void scaleCanvasToViewBox(Canvas canvas, Size desiredSize, Rect viewBox) { - final double xscale = desiredSize.width / viewBox.size.width; - final double yscale = desiredSize.height / viewBox.size.height; - - if (xscale == yscale) { - canvas.scale(xscale, yscale); - } else if (xscale < yscale) { - final double xtranslate = (viewBox.size.width - viewBox.size.height) / 2; - canvas.scale(xscale, xscale); - canvas.translate(0.0, xtranslate); - } else { - final double ytranslate = (viewBox.size.height - viewBox.size.width) / 2; - canvas.scale(yscale, yscale); - canvas.translate(ytranslate, 0.0); - } + final double scale = math.min( + desiredSize.width / viewBox.width, desiredSize.height / viewBox.height); + final Offset shift = desiredSize / 2.0 - viewBox.size * scale / 2.0; + canvas.translate(shift.dx, shift.dy); + canvas.scale(scale, scale); } diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 96210091fc5d..97aa6188be84 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -1,9 +1,11 @@ import 'dart:typed_data'; import 'dart:ui'; -import 'package:path_drawing/path_drawing.dart'; import 'package:flutter/widgets.dart' hide TextStyle; import 'package:meta/meta.dart'; +import 'package:path_drawing/path_drawing.dart'; + +import 'render_picture.dart' as render_picture; typedef Paint PaintServer(Rect bounds); @@ -220,20 +222,7 @@ class DrawableRoot implements Drawable { /// the smaller dimension and translate to center the image along the larger /// dimension. void scaleCanvasToViewBox(Canvas canvas, Size desiredSize) { - final double xscale = desiredSize.width / viewBox.size.width; - final double yscale = desiredSize.height / viewBox.size.height; - - if (xscale == yscale) { - canvas.scale(xscale, yscale); - } else if (xscale < yscale) { - final double xtranslate = (viewBox.size.width - viewBox.size.height) / 2; - canvas.scale(xscale, xscale); - canvas.translate(0.0, xtranslate); - } else { - final double ytranslate = (viewBox.size.height - viewBox.size.width) / 2; - canvas.scale(yscale, yscale); - canvas.translate(ytranslate, 0.0); - } + render_picture.scaleCanvasToViewBox(canvas, desiredSize, viewBox); } /// Clips the canvas to a rect corresponding to the `viewBox`. From 1528f4c3f40701926b5bb0cc3f85e16fc25c54de Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Fri, 8 Jun 2018 21:30:18 +0200 Subject: [PATCH 097/512] fixed path handling on Windows You have to use Platform.script.toFilePath() instead of Platform.script.path because the latter is the path part of a Uri, but we want an actual file system path. --- third_party/test/render_svg_test.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/third_party/test/render_svg_test.dart b/third_party/test/render_svg_test.dart index c6381f090c1d..8550b68bae6f 100644 --- a/third_party/test/render_svg_test.dart +++ b/third_party/test/render_svg_test.dart @@ -8,8 +8,9 @@ import 'package:test/test.dart'; import '../tool/gen_golden.dart' as golden; Iterable getGoldenFileNames() sync* { - final Directory dir = new Directory(join(dirname(Platform.script.path), - dirname(Platform.script.path).endsWith('test') ? '..' : '', 'golden')); + final String root = dirname(Platform.script.toFilePath()); + final Directory dir = new Directory(join(root, + root.endsWith('test') ? '..' : '', 'golden')); for (FileSystemEntity fe in dir.listSync(recursive: true)) { if (fe is File && fe.path.toLowerCase().endsWith('.png')) { yield fe; From e0fe5a544f61aa5c5e05ad2b8e8fd83662e99844 Mon Sep 17 00:00:00 2001 From: Waldemar Kornewald Date: Sat, 9 Jun 2018 08:15:40 +0200 Subject: [PATCH 098/512] color percentages can be floats, rgb is case-insensitive, allow whitespace --- third_party/lib/src/svg/colors.dart | 20 +++++++++----------- third_party/test/colors_svg_test.dart | 2 ++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/third_party/lib/src/svg/colors.dart b/third_party/lib/src/svg/colors.dart index d090c1b62e11..08f77957da01 100644 --- a/third_party/lib/src/svg/colors.dart +++ b/third_party/lib/src/svg/colors.dart @@ -32,20 +32,18 @@ Color parseColor(String colorString) { } // handle rgb() colors e.g. rgb(255, 255, 255) - if (colorString.startsWith('rgb')) { + if (colorString.toLowerCase().startsWith('rgb')) { final List rgb = colorString .substring(colorString.indexOf('(') + 1, colorString.indexOf(')')) .split(',') - .map( - (String rawColor) { - if (rawColor.endsWith('%')) { - final int percentage = - int.parse(rawColor.substring(0, rawColor.length - 1)); - return (percentage * 2.55).round(); - } - return int.parse(rawColor); - }, - ).toList(); + .map((String rawColor) { + rawColor = rawColor.trim(); + if (rawColor.endsWith('%')) { + rawColor = rawColor.substring(0, rawColor.length - 1); + return (double.parse(rawColor) * 2.55).round(); + } + return int.parse(rawColor); + }).toList(); // rgba() isn't really in the spec, but Firefox supported it at one point so why not. final int a = rgb.length > 3 ? rgb[3] : 255; diff --git a/third_party/test/colors_svg_test.dart b/third_party/test/colors_svg_test.dart index 5f17b7cd5619..91c56da6ad43 100644 --- a/third_party/test/colors_svg_test.dart +++ b/third_party/test/colors_svg_test.dart @@ -11,6 +11,8 @@ void main() { expect(parseColor('white'), white); expect(parseColor('rgb(255, 255, 255)'), white); expect(parseColor('rgb(100%, 100%, 100%)'), white); + expect(parseColor('RGB( 100% , 100.0% , 99.9999% )'), white); + expect(parseColor('rGb( .0%,0.0%,.0000001% )'), black); expect(parseColor('rgba(255,255, 255, 255)'), white); expect(parseColor('#DDFFFFFF'), const Color(0xDDFFFFFF)); expect(parseColor(''), black); From 9d6b2e042df558f4600890a92640532861278198 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 10 Jun 2018 14:19:57 -0400 Subject: [PATCH 099/512] bump version to v0.3.3 --- third_party/CHANGELOG.md | 5 +++++ third_party/pubspec.lock | 2 +- third_party/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 01061ba01859..69996d720e35 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 0.3.3 + +- Fix centering/scaling of canvas when viewBox is not square +- Improved color parsing + ## 0.3.2 - Bug fix around caching for tinting/coloring (color was not being properly included in cache keys) diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 9947aa1714e1..5b3345c97fb2 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -388,5 +388,5 @@ packages: source: hosted version: "2.1.13" sdks: - dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.58.0.flutter-f981f09760" + dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.60.0.flutter-a5e41681e5" flutter: ">=0.3.6 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 5b752bf45954..557d5a0f6592 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.3.2 +version: 0.3.3 dependencies: path_drawing: ^0.2.3 From fb02d555080230587fe8b5159b013c7548a159f8 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 12 Jun 2018 11:37:11 -0400 Subject: [PATCH 100/512] remove deprecated code. add better error reporting for unsupported style element --- third_party/example/main.dart | 3 +- third_party/lib/avd.dart | 183 +++++++++++++++------- third_party/lib/src/picture_provider.dart | 14 +- third_party/lib/src/svg/xml_parsers.dart | 6 +- third_party/lib/src/svg_parser.dart | 40 ++++- third_party/lib/src/vector_painter.dart | 28 ---- third_party/lib/svg.dart | 166 ++------------------ third_party/lib/vector_drawable.dart | 101 ------------ 8 files changed, 193 insertions(+), 348 deletions(-) delete mode 100644 third_party/lib/src/vector_painter.dart delete mode 100644 third_party/lib/vector_drawable.dart diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 0e24452a1aa5..a01ba3b7c434 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -115,8 +115,7 @@ class _MyHomePageState extends State { ), ); } - _painters.add(new AvdImage.asset('assets/android_vd/battery_charging.xml', - new Size(_dimension, _dimension))); + _painters.add(new AvdPicture.asset('assets/android_vd/battery_charging.xml')); } @override diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 58d6f20aef4f..1bdbb9580966 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -1,78 +1,155 @@ -// ignore_for_file: deprecated_member_use import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'dart:typed_data'; +import 'dart:ui' show Picture; import 'package:flutter/services.dart' show rootBundle, AssetBundle; import 'package:flutter/widgets.dart'; import 'package:xml/xml.dart' hide parse; import 'package:xml/xml.dart' as xml show parse; +import './svg.dart'; import 'src/avd/xml_parsers.dart'; import 'src/avd_parser.dart'; +import 'src/picture_provider.dart'; +import 'src/picture_stream.dart'; import 'src/vector_drawable.dart'; -import 'vector_drawable.dart'; + +final Avd avd = new Avd._(); + +class Avd { + Avd._(); + + FutureOr avdPictureDecoder( + Uint8List raw, + bool allowDrawingOutsideOfViewBox, + ColorFilter colorFilter, + String key) async { + final DrawableRoot avdRoot = await fromAvdBytes(raw, key); + final Picture pic = avdRoot.toPicture( + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, + colorFilter: colorFilter); + return new PictureInfo(picture: pic, viewBox: avdRoot.viewBox); + } + + FutureOr avdPictureStringDecoder(String raw, + bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter, String key) { + final DrawableRoot svg = fromAvdString(raw, key); + return new PictureInfo( + picture: svg.toPicture( + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, + colorFilter: colorFilter), + viewBox: svg.viewBox); + } + + FutureOr fromAvdBytes(Uint8List raw, String key) async { + // TODO - do utf decoding in another thread? + // Might just have to live with potentially slow(ish) decoding, this is causing errors. + // See: https://github.com/dart-lang/sdk/issues/31954 + // See: https://github.com/flutter/flutter/blob/bf3bd7667f07709d0b817ebfcb6972782cfef637/packages/flutter/lib/src/services/asset_bundle.dart#L66 + // if (raw.lengthInBytes < 20 * 1024) { + return fromAvdString(utf8.decode(raw), key); + // } else { + // final String str = + // await compute(_utf8Decode, raw, debugLabel: 'UTF8 decode for SVG'); + // return fromSvgString(str); + // } + } + + // String _utf8Decode(Uint8List data) { + // return utf8.decode(data); + // } + + /// Creates a [DrawableRoot] from a string of Android Vector Drawable data. + DrawableRoot fromAvdString(String rawSvg, String key) { + final XmlElement svg = xml.parse(rawSvg).rootElement; + final Rect viewBox = parseViewBox(svg); + final List children = svg.children + .where((XmlNode child) => child is XmlElement) + .map((XmlNode child) => parseAvdElement( + child, + new Rect.fromPoints( + Offset.zero, new Offset(viewBox.width, viewBox.height)))) + .toList(); + // todo : style on root + return new DrawableRoot( + viewBox, children, new DrawableDefinitionServer(), null); + } +} /// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. -class AvdImage extends VectorDrawableImage { - const AvdImage._(Future future, Size size, +class AvdPicture extends SvgPicture { + const AvdPicture(PictureProvider pictureProvider, {Key key, - PaintLocation paintLocation, - ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) - : super(future, size, + bool matchTextDirection = false, + bool allowDrawingOutsideViewBox = false, + WidgetBuilder placeholderBuilder}) + : super(pictureProvider, key: key, - paintLocation: paintLocation, - errorWidgetBuilder: errorWidgetBuilder, - loadingPlaceholderBuilder: loadingPlaceholderBuilder); + matchTextDirection: matchTextDirection, + allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, + placeholderBuilder: placeholderBuilder); - factory AvdImage.fromString(String svg, Size size, - {Key key, - PaintLocation paintLocation = PaintLocation.background, - ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) { - return new AvdImage._( - new Future.value(fromAvdString(svg, size)), - size, - key: key, - paintLocation: paintLocation, - errorWidgetBuilder: errorWidgetBuilder, - loadingPlaceholderBuilder: loadingPlaceholderBuilder, - ); - } + AvdPicture.string(String bytes, + {bool matchTextDirection = false, + bool allowDrawingOutsideViewBox = false, + WidgetBuilder placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn, + Key key}) + : this( + new StringPicture( + allowDrawingOutsideViewBox == true + ? avdStringDecoderOutsideViewBox + : avdStringDecoder, + bytes, + colorFilter: _getColorFilter(color, colorBlendMode)), + matchTextDirection: matchTextDirection, + allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, + placeholderBuilder: placeholderBuilder, + key: key); - factory AvdImage.asset(String assetName, Size size, + AvdPicture.asset(String assetName, {Key key, + bool matchTextDirection = false, AssetBundle bundle, String package, - PaintLocation paintLocation = PaintLocation.background, - ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) { - return new AvdImage._( - loadAsset(assetName, size, bundle: bundle, package: package), - size, - key: key, - paintLocation: paintLocation, - errorWidgetBuilder: errorWidgetBuilder, - loadingPlaceholderBuilder: loadingPlaceholderBuilder, - ); - } + bool allowDrawingOutsideViewBox = false, + WidgetBuilder placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn}) + : this( + new ExactAssetPicture( + allowDrawingOutsideViewBox == true + ? avdByteDecoderOutsideViewBox + : avdByteDecoder, + assetName, + bundle: bundle, + package: package, + colorFilter: _getColorFilter(color, colorBlendMode)), + matchTextDirection: matchTextDirection, + allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, + placeholderBuilder: placeholderBuilder, + key: key); - factory AvdImage.network(String uri, Size size, - {Map headers, - Key key, - PaintLocation paintLocation = PaintLocation.background, - ErrorWidgetBuilder errorWidgetBuilder, - WidgetBuilder loadingPlaceholderBuilder}) { - return new AvdImage._( - loadNetworkAsset(uri, size), - size, - key: key, - paintLocation: paintLocation, - errorWidgetBuilder: errorWidgetBuilder, - loadingPlaceholderBuilder: loadingPlaceholderBuilder, - ); - } + static ColorFilter _getColorFilter(Color color, BlendMode colorBlendMode) => + color == null + ? null + : new ColorFilter.mode(color, colorBlendMode ?? BlendMode.srcIn); + + static final PictureInfoDecoder avdByteDecoder = + (Uint8List bytes, ColorFilter colorFilter, String key) => + avd.avdPictureDecoder(bytes, false, colorFilter, key); + static final PictureInfoDecoder avdStringDecoder = + (String data, ColorFilter colorFilter, String key) => + avd.avdPictureStringDecoder(data, false, colorFilter, key); + static final PictureInfoDecoder avdByteDecoderOutsideViewBox = + (Uint8List bytes, ColorFilter colorFilter, String key) => + avd.avdPictureDecoder(bytes, true, colorFilter, key); + static final PictureInfoDecoder avdStringDecoderOutsideViewBox = + (String data, ColorFilter colorFilter, String key) => + avd.avdPictureStringDecoder(data, true, colorFilter, key); } /// Creates a [DrawableRoot] from a string of SVG data. diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index c76f47fd0fe1..462d73a2d37a 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -17,7 +17,7 @@ import 'picture_cache.dart'; import 'picture_stream.dart'; typedef FutureOr PictureInfoDecoder( - T data, ColorFilter colorFilter); + T data, ColorFilter colorFilter, String key); /// Creates an [PictureConfiguration] based on the given [BuildContext] (and /// optionally size). @@ -421,7 +421,7 @@ abstract class AssetBundlePictureProvider throw 'Unable to read data'; } - return await decoder(data.buffer.asUint8List(), key.colorFilter); + return await decoder(data.buffer.asUint8List(), key.colorFilter, key.toString()); } } @@ -480,7 +480,7 @@ class NetworkPicture extends PictureProvider { } final Uint8List bytes = await consolidateHttpClientResponseBytes(response); - return await decoder(bytes, colorFilter); + return await decoder(bytes, colorFilter, key.toString()); } @override @@ -544,7 +544,7 @@ class FilePicture extends PictureProvider { return null; } - return await decoder(data, colorFilter); + return await decoder(data, colorFilter, key.toString()); } @override @@ -605,7 +605,7 @@ class MemoryPicture extends PictureProvider { Future _loadAsync(MemoryPicture key) async { assert(key == this); - return await decoder(bytes, colorFilter); + return await decoder(bytes, colorFilter, key.toString()); } @override @@ -652,7 +652,7 @@ class StringPicture extends PictureProvider { Future _loadAsync(StringPicture key) async { assert(key == this); - return await decoder(string, colorFilter); + return await decoder(string, colorFilter, key.toString()); } @override @@ -668,7 +668,7 @@ class StringPicture extends PictureProvider { int get hashCode => hashValues(string.hashCode, colorFilter); @override - String toString() => '$runtimeType($string, colorFilter: $colorFilter)'; + String toString() => '$runtimeType(${describeIdentity(string)}, colorFilter: $colorFilter)'; } /// Fetches a picture from an [AssetBundle], associating it with the given scale. diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 337f977c7496..a2ec6c7efb2f 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -55,13 +55,17 @@ Rect parseViewBox(XmlElement svg) { String buildUrlIri(XmlElement def) => 'url(#${getAttribute(def, 'id')})'; /// Parses a element, extracting and (TODO) elements into the `paintServers` map. -void parseDefs(XmlElement el, DrawableDefinitionServer definitions) { +/// +/// Returns any elements it was not able to process. +Iterable parseDefs(XmlElement el, DrawableDefinitionServer definitions) sync* { for (XmlNode def in el.children) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { definitions.addPaintServer(buildUrlIri(def), parseGradient(def)); } else if (def.name.local == 'clipPath') { definitions.addClipPath(buildUrlIri(def), parseClipPathDefinition(def)); + } else { + yield def; } } } diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index a818a9b57abe..25882d28cc7d 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +import 'package:flutter/foundation.dart'; import 'package:xml/xml.dart'; import 'package:vector_math/vector_math_64.dart'; @@ -35,29 +36,55 @@ class DrawableSvgShape extends DrawableShape { /// /// If an unsupported element is encountered, it will be created as a [DrawableNoop]. Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, - Rect bounds, DrawableStyle parentStyle) { + Rect bounds, DrawableStyle parentStyle, String key) { + final Function unhandled = (XmlElement e) => _unhandledElement(e, key); + final SvgPathFactory shapeFn = svgPathParsers[el.name.local]; if (shapeFn != null) { return new DrawableSvgShape.parse(shapeFn, definitions, el, parentStyle); } else if (el.name.local == 'defs') { - parseDefs(el, definitions); + parseDefs(el, definitions).forEach(unhandled); return new DrawableNoop(el.name.local); } else if (el.name.local.endsWith('Gradient')) { definitions.addPaintServer( 'url(#${getAttribute(el, 'id')})', parseGradient(el)); return new DrawableNoop(el.name.local); } else if (el.name.local == 'g' || el.name.local == 'a') { - return parseSvgGroup(el, definitions, bounds, parentStyle); + return parseSvgGroup(el, definitions, bounds, parentStyle, key); } else if (el.name.local == 'text') { return parseSvgText(el, definitions, bounds, parentStyle); } else if (el.name.local == 'svg') { throw new UnsupportedError( 'Nested SVGs not supported in this implementation.'); } - print('Unhandled element ${el.name.local}'); + + unhandled(el); return new DrawableNoop(el.name.local); } +void _unhandledElement(XmlElement el, String key) { + if (el.name.local == 'style') { + FlutterError.reportError(new FlutterErrorDetails( + exception: new UnimplementedError('The

U1T*o0n0|_RhpvqVp8)WF$Kxt(=;c5z58-;$k z^cRtCzT|I{HTpiLD^EuKBng!T6&eZoF@B7+95Y{+^-vOI-Fx_Y>u*}hy*G|D^DJb=Hv|4 z%J7cdM~gL)xL>+wS8SS_BX*eqD*L}8YXs5?enDEI%J18{hbAid&Y|+~B9AXNp7(*7nTNI>X0t6BQ%qhaS)yUtQy$!*< zCb5V3e;|#&lSi?q8gXK_MnHV4_U#^^)pS>@=qbP9%repLxjo<5(ew!8kc5u~=~X`i4GzPDZX2suG3~9@ zH`}+~#E$yagb>IN62_rl?_3Pfl%+!k4&SUhbT;q^sTAHIhuhAbJ7#a^t+#k`tSGNy z;bW(7vsw~{%^Jj)rn5$qLubF;Xl~9#W&oV?98wxL?6Z;R(^V&EE4s?*l8UWMn?^cc zzE+1W&Mpiuc#$(Xrk|uTMs>9QunjQD*j&oO?m0QdvtGanbu__>t+ja2t9^Ufnl(mur=EP>Tfmrt2#q&2$PWdYdufOB4T-!(?y>q={q;l%{V5k~-&10DpiT2;q z*mYbMjCqRXm8l<~l;Hb+`lc${=Ihd*7sflR(7=EnR1~Xguq`QsaQI96+>JyS(^O=` zaohXSGmn1idS>n1R-%Vh>k@e|q9!GJ=7KwCaLr5bj!rdNJL;o!x~AH+bT@+sVh6UP zrn8MuH$NDvCNYr)icnt{rToosCO3p?AM-90 z5HkJ4sl8Xey7E%mHUlkE+S`6o`t169Bh}qJ9p3uI7x$2kU2PL;-!ewiP{wB8_J^kl z&3o87D04fPOKp3={hnQhrig3^Y+~Uf@bk57(OYHTd9!SZ)QjPbkp}$1kdKON?x#g> zY;Hkn8Woz{0qASX-V}QuY$Ht?Y<-)~neN%!*$kEi&-0dhN9wGs^Zn)Fb$Dn)np9G- zBp&agfZ3V%l_i_`~2i5A3!k)x?smoae#lKJ(> z`L~elkm~8Inx^s`AAi~s*?)Wm)c`FVDK27U-{`w!Fg1;TQ>xt8^;(k)&)g}B5WS8w z7QpbA`1AjZ$>>LR6GS4tq)_+u^=k>6(!o3o_2T}MKlX_#mN5* zqM&_5Zf9n+F=GgE-0B@LcP50;`{jV7sE&%dOw39Y7}2$3&}N}`Mx)0)4}w)m*F9Ma zVK#gsd@5|#VAV{`iR!)6?|FY%o{|8SnJ_W{CWE3=6LyVyLgLztA*98!IFGq kB4oX&FY>?nvXRHYM%P-AS1b0k?#apibfc1%T~I5C8xG literal 0 HcmV?d00001 diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index 0386e526bd3e..1e17f9b059b7 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -24,8 +24,8 @@ Rect parseViewBox(XmlElement el) { } Matrix4 parseTransform(XmlElement el) { - final double rotation = double - .parse(getAttribute(el, 'rotation', def: '0', namespace: androidNS)); + final double rotation = double.parse( + getAttribute(el, 'rotation', def: '0', namespace: androidNS)); final double pivotX = double.parse(getAttribute(el, 'pivotX', def: '0', namespace: androidNS)); final double pivotY = @@ -34,10 +34,10 @@ Matrix4 parseTransform(XmlElement el) { double.parse(getAttribute(el, 'scaleX', def: '1', namespace: androidNS)); final double scaleY = double.parse(getAttribute(el, 'scaleY', def: '1', namespace: androidNS)); - final double translateX = double - .parse(getAttribute(el, 'translateX', def: '0', namespace: androidNS)); - final double translateY = double - .parse(getAttribute(el, 'translateY', def: '0', namespace: androidNS)); + final double translateX = double.parse( + getAttribute(el, 'translateX', def: '0', namespace: androidNS)); + final double translateY = double.parse( + getAttribute(el, 'translateY', def: '0', namespace: androidNS)); return new Matrix4.identity() ..translate(pivotX, pivotY) @@ -54,10 +54,10 @@ Paint parseStroke(XmlElement el, Rect bounds) { } return new Paint() ..style = PaintingStyle.stroke - ..color = parseColor(rawStroke).withOpacity(double - .parse(getAttribute(el, 'strokeAlpha', def: '1', namespace: androidNS))) - ..strokeWidth = double - .parse(getAttribute(el, 'strokeWidth', def: '0', namespace: androidNS)) + ..color = parseColor(rawStroke).withOpacity(double.parse( + getAttribute(el, 'strokeAlpha', def: '1', namespace: androidNS))) + ..strokeWidth = double.parse( + getAttribute(el, 'strokeWidth', def: '0', namespace: androidNS)) ..strokeCap = parseStrokeCap(el) ..strokeJoin = parseStrokeJoin(el) ..strokeMiterLimit = parseMiterLimit(el); diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index faee64910cae..a79fdc3dd764 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -476,7 +476,7 @@ class NetworkPicture extends PictureProvider { final HttpClientRequest request = await _httpClient.getUrl(uri); final HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.OK) { + if (response.statusCode != HttpStatus.ok) { throw new HttpException('Could not get network asset', uri: uri); } final Uint8List bytes = await consolidateHttpClientResponseBytes(response); diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart index 2234bbb56c22..a922ed6ee6f3 100644 --- a/third_party/lib/src/picture_stream.dart +++ b/third_party/lib/src/picture_stream.dart @@ -151,7 +151,7 @@ class PictureStream extends Diagnosticable { 'listeners', _listeners, ifPresent: - '${_listeners?.length} listener${_listeners?.length == 1 ? "" : "s" }', + '${_listeners?.length} listener${_listeners?.length == 1 ? "" : "s"}', ifNull: 'no listeners', level: _completer != null ? DiagnosticLevel.hidden : DiagnosticLevel.info, )); @@ -234,7 +234,7 @@ abstract class PictureStreamCompleter extends Diagnosticable { 'listeners', _listeners, ifPresent: - '${_listeners?.length} listener${_listeners?.length == 1 ? "" : "s" }', + '${_listeners?.length} listener${_listeners?.length == 1 ? "" : "s"}', )); } } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 80a627c8af06..eeac9534c01e 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -288,8 +288,25 @@ double parseOpacity(XmlElement el) { return null; } +Paint _changePaintColor(Paint src, Color newColor) { + return new Paint() + ..blendMode = src.blendMode + ..color = newColor + ..colorFilter = src.colorFilter + ..filterQuality = src.filterQuality + ..isAntiAlias = src.isAntiAlias + ..maskFilter = src.maskFilter + ..shader = src.shader + ..strokeCap = src.strokeCap + ..strokeJoin = src.strokeJoin + ..strokeMiterLimit = src.strokeMiterLimit + ..strokeWidth = src.strokeWidth + ..style = src.style; +} + Paint _getDefinitionPaint( - String iri, DrawableDefinitionServer definitions, Rect bounds) { + String iri, DrawableDefinitionServer definitions, Rect bounds, + {double opacity}) { final Paint paint = definitions.getPaint(iri, bounds); if (paint == null) { FlutterError.onError( @@ -308,6 +325,9 @@ Paint _getDefinitionPaint( ), ); } + if (opacity != null) { + return _changePaintColor(paint, paint.color.withOpacity(opacity)); + } return paint; } @@ -359,24 +379,24 @@ Paint parseStroke( Paint parseFill(XmlElement el, Rect bounds, DrawableDefinitionServer definitions, Color defaultFillIfNotSpecified) { final String rawFill = getAttribute(el, 'fill'); + final String rawOpacity = getAttribute(el, 'fill-opacity'); + + final double opacity = + rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); + if (rawFill == '') { if (defaultFillIfNotSpecified == null) { return null; } - return new Paint()..color = defaultFillIfNotSpecified; + return new Paint()..color = defaultFillIfNotSpecified.withOpacity(opacity); } else if (rawFill == 'none') { return DrawableStyle.emptyPaint; } if (rawFill.startsWith('url')) { - return _getDefinitionPaint(rawFill, definitions, bounds); + return _getDefinitionPaint(rawFill, definitions, bounds, opacity: opacity); } - final String rawOpacity = getAttribute(el, 'fill-opacity'); - final double opacity = rawOpacity == '' - ? rawFill == 'none' ? 0.0 : 1.0 - : double.parse(rawOpacity).clamp(0.0, 1.0); - final Color fill = parseColor(rawFill).withOpacity(opacity); return new Paint() diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 7c4c9b37f89f..8653d1bbc123 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -22,7 +22,12 @@ class DrawableSvgShape extends DrawableShape { DrawableStyle parentStyle) { assert(pathFactory != null); - final Color defaultFill = parentStyle?.fill != null ? null : colorBlack; + final Color defaultFill = parentStyle == null || parentStyle.fill == null + ? colorBlack + : identical(parentStyle.fill, DrawableStyle.emptyPaint) + ? null + : parentStyle.fill.color; + final Path path = pathFactory(el); return new DrawableSvgShape( applyTransformIfNeeded(path, el), diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 9b98714d497d..193e065f89ae 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -30,7 +30,7 @@ class DrawableStyle { /// This will not result in a drawing operation, but will clear out /// inheritance. Modifying this paint should not result in any changes to /// the image, but it should not be modified. - static final Paint emptyPaint = new Paint(); + static final Paint emptyPaint = new Paint()..color = const Color(0x00000000); /// Used where 'dasharray' is 'none' /// diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index d9b008ad02a9..c604d39a5299 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -7,35 +7,35 @@ packages: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.31.2-alpha.2" + version: "0.32.4" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.4.3" + version: "1.4.4" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.0.7" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: @@ -49,21 +49,21 @@ packages: name: convert url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.2" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.6" csslib: dependency: transitive description: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.14.4" + version: "0.14.4+1" flutter: dependency: "direct main" description: flutter @@ -80,28 +80,28 @@ packages: name: front_end url: "https://pub.dartlang.org" source: hosted - version: "0.1.0-alpha.12" + version: "0.1.4" glob: dependency: transitive description: name: glob url: "https://pub.dartlang.org" source: hosted - version: "1.1.5" + version: "1.1.7" html: dependency: transitive description: name: html url: "https://pub.dartlang.org" source: hosted - version: "0.13.3+1" + version: "0.13.3+2" http: dependency: transitive description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.11.3+16" + version: "0.11.3+17" http_multi_server: dependency: transitive description: @@ -115,49 +115,49 @@ packages: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.2" + version: "3.1.3" io: dependency: transitive description: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.2+1" + version: "0.3.3" js: dependency: transitive description: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.1" + version: "0.6.1+1" json_rpc_2: dependency: transitive description: name: json_rpc_2 url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.0.9" kernel: dependency: transitive description: name: kernel url: "https://pub.dartlang.org" source: hosted - version: "0.3.0-alpha.12" + version: "0.3.4" logging: dependency: transitive description: name: logging url: "https://pub.dartlang.org" source: hosted - version: "0.11.3+1" + version: "0.11.3+2" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.2" + version: "0.12.2+1" meta: dependency: "direct main" description: @@ -171,7 +171,7 @@ packages: name: mime url: "https://pub.dartlang.org" source: hosted - version: "0.9.6+1" + version: "0.9.6+2" mockito: dependency: "direct dev" description: @@ -185,35 +185,35 @@ packages: name: multi_server_socket url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" node_preamble: dependency: transitive description: name: node_preamble url: "https://pub.dartlang.org" source: hosted - version: "1.4.2" + version: "1.4.4" package_config: dependency: transitive description: name: package_config url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.5" package_resolver: dependency: transitive description: name: package_resolver url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.4" path: dependency: "direct dev" description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.1" + version: "1.6.2" path_drawing: dependency: "direct main" description: @@ -227,63 +227,63 @@ packages: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "1.7.6" + version: "1.7.7" plugin: dependency: transitive description: name: plugin url: "https://pub.dartlang.org" source: hosted - version: "0.2.0+2" + version: "0.2.0+3" pool: dependency: transitive description: name: pool url: "https://pub.dartlang.org" source: hosted - version: "1.3.5" + version: "1.3.6" pub_semver: dependency: transitive description: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.4.1" + version: "1.4.2" quiver: dependency: transitive description: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "0.29.0+1" + version: "2.0.0+1" shelf: dependency: transitive description: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "0.7.3+1" + version: "0.7.3+3" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.4" shelf_static: dependency: transitive description: name: shelf_static url: "https://pub.dartlang.org" source: hosted - version: "0.2.7+1" + version: "0.2.8" shelf_web_socket: dependency: transitive description: name: shelf_web_socket url: "https://pub.dartlang.org" source: hosted - version: "0.2.2+2" + version: "0.2.2+3" sky_engine: dependency: transitive description: flutter @@ -295,49 +295,49 @@ packages: name: source_map_stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.1.4" + version: "1.1.5" source_maps: dependency: transitive description: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.5" + version: "0.10.7" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.4.0" + version: "1.4.1" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.2" + version: "1.9.3" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "1.6.7+1" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.0.3" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.1" test: dependency: "direct dev" description: @@ -358,49 +358,49 @@ packages: name: utf url: "https://pub.dartlang.org" source: hosted - version: "0.9.0+4" + version: "0.9.0+5" vector_math: dependency: "direct main" description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.6" + version: "2.0.8" vm_service_client: dependency: transitive description: name: vm_service_client url: "https://pub.dartlang.org" source: hosted - version: "0.2.4+3" + version: "0.2.6" watcher: dependency: transitive description: name: watcher url: "https://pub.dartlang.org" source: hosted - version: "0.9.7+8" + version: "0.9.7+10" web_socket_channel: dependency: transitive description: name: web_socket_channel url: "https://pub.dartlang.org" source: hosted - version: "1.0.8" + version: "1.0.9" xml: dependency: "direct main" description: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.0.1" yaml: dependency: transitive description: name: yaml url: "https://pub.dartlang.org" source: hosted - version: "2.1.14" + version: "2.1.15" sdks: - dart: ">=2.0.0-dev.62.0 <=2.0.0-dev.63.0.flutter-4c9689c1d2" + dart: ">=2.0.0-dev.62.0 <=2.0.0-dev.69.4.flutter-08f59e5de3" flutter: ">=0.5.1 <2.0.0" From cbba590de4b910c712233a79d19c2700539f9f6e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 31 Jul 2018 15:51:29 -0400 Subject: [PATCH 129/512] fix stroke --- .../assets/simple/group_fill_opacity.svg | 6 ++--- .../golden/simple/group_fill_opacity.png | Bin 2916 -> 6418 bytes .../golden/wikimedia/Ghostscript_Tiger.png | Bin 44515 -> 47211 bytes third_party/lib/src/svg/xml_parsers.dart | 22 ++++++++++++------ third_party/lib/src/svg_parser.dart | 16 ++++++++++--- third_party/lib/src/vector_drawable.dart | 2 ++ 6 files changed, 33 insertions(+), 13 deletions(-) diff --git a/third_party/assets/simple/group_fill_opacity.svg b/third_party/assets/simple/group_fill_opacity.svg index 935e9e95862e..7a8e04f6604c 100644 --- a/third_party/assets/simple/group_fill_opacity.svg +++ b/third_party/assets/simple/group_fill_opacity.svg @@ -1,8 +1,8 @@ - - + + @@ -15,7 +15,7 @@ - + diff --git a/third_party/golden/simple/group_fill_opacity.png b/third_party/golden/simple/group_fill_opacity.png index d844543e2c4ffc8860add834270a72a9f793bad0..3905d45aa9a62b38af3017af90f79a5e99c97324 100644 GIT binary patch literal 6418 zcmb`MX*65kyT?P27!##6)DW~qTVp8|L&Qvtt(u2YQ_X^?5K~G={8~k6W2h=>u9|A5 zC^b}7%=1hIMFf$X{_njn?u+~4-t|9gowLt5`>eB`^_;!G`}=v$V>1&yb{2jX006*l zps#H~YrFsMU?$qJ#JUtuYv@oGdPqQNzrY&pf&qmzxDBRl5#W1|007iaT~#4ZYKB5fG+dLuDmf%-kbY3H0QJT)%8V!axfJ9F92{{8NA}PrM1v~9I%(-=G5Y~jHRi5MxZ;__TbLq-I zyb}?0BBzFw9}b?GsjP&!q{D_gtD9cs#Su*Ds$;Syv`()nm8xpG{wRm;5BPkMhy&kb zb;_u$&zAQ&kxM@~1aL3X+sd*f=$}7FnEw-)KEncDgSW2XRIa}EHV*N*6mZ&b_ZdC% z^+tQi7)H#-{IMvDj+^M8C`KCLR< z`ccSddvBJ{Jkhnv?YxY*!;3oy6R@{sv$nU&LG-R&{GInoufX!kQl%fNsng-B0?oSI zjvDN{C%=gFXR?m|jt?BS`R7n333Sx`k7u(O#Bf&v25TAa-Jpv}ewx@4bZ}uYK{z&G zV9F6C0qdapPB1lAv4vZHE=)V?;tJE&p}*!qztDx&NT5gR53Gv3g)&hi^krl~3VoB_ z<30$BGcfS7BOz^kJo=MIpVOagO+;929bxaHG4THV=w)|Q*~bk;xC-it6Qeej^spuW zx!KnDht}b3liuPNH7~2MTn(ddt9+mDI1y}VX@=cV$fF$3@@p_#M85S(8_{9j{d!q~ z3*{W?&Yb+pZTxejOBYA2;}nB2BkmjuIHc}#p>3Dca?M};s@-+E7mJEr{&>ydu8p0G1D4ZGV|q@y~;6;JP4S_aHqJO69IKTg~$Z=k0;ghzJqo2qrS ze|)-Jr$@*s=hl>eYu%1wt>Yi7ar2JXR2q(-NtX_3uK2mC(Pzk4PKQR{9kam=#3le@Gm zX>U~hd>|%hPLz-lnNxkm(_o)sI{4-O8+ld7V2|Gp+q zAKY*oDbXtUvsOXjob4x>#Yz|O8{%n6$gk*LH{K1Z6%=_w8-@R_F-{SNX0qRRIWvAoUHH?Y$2kD$AZpeA!hy!X|kF=fN$0X?46dGx*}las6}!soINL@Uk*wA9O1?k~n>O>U!{acTpxd z#51m zckUOsRrZ^UOg5|WOIWsmy*if}?nV1N^DX-NPkHDhCDlwfSFnRpcdYjJ2f5A!?u@Yq ze8|&cWs~3Et@nxfy%@-lCZuUr3`~864SxgykV@48{Kg*E7pvME_u&99sTmS1v8F;g zC;h*YXCluJ9kLN`UXYvLXcKL~2pQ9JQy^_b= z#>zBlt-{0M#uHY#^@W-C$`zTnz1uIbgIY(5wq7^vzrCv)35M`3hd3KGe=Lm2XP#`M z1NgRg0hT_nxta`k*A_ii_3N8mMu@EvE@B77v{aRc|#pH|&mZwnqWS3C20wCc8J% z7V29DIOq!tX>;PTnqUsuKTyi6?CQheA?Hc`anmDBx;ovSUY&q7PQU%dr@x?QxF|9( zfGTQ5Z1H1K-7nTFlF^5=z<9Z+H4x)s{S6e9djqlev`OQEVUzW9k=|wGboJQE=To87 zl1y0_0*kU?)AoZB+Kdq^oriWTDft|)iBq!Qp7qa`A)i%^qJZ%^?IIG(LZXG8Y`QHT zAlQXVi0K0+*|73Lf|4Z$u3Gmg=7o!b$!kXMw{_y?lE7T3MHm1X8cGs}JN%rXr80PB zcPUZu;QRD&p9`Jtv+drABB8f%!p`S_y6=sC0Rdexua({~kCtFJL4S2BoJjgmDE>sdP(#=G8s`A zuJaRtm}__GG58|-V-oPyD}?L2I`2o1R+W`K#;c}R4qP=D90>dQM$#wY=5QAEw18?u zc}jW8wi$bkyZ2$AE%VO1LqGkKx2q~CUe|uy7mQ9_z2KRAv$0_wtQAJ)0s9o_v=E(` zE}3kG;;YH*wFglQI#q2quClv)dF*iyOkbSl4J(vp=+HqNP5FPxva)0(K=R*RRN>>% zGl_ZsYcg8mI^1PI0NMQtRUWZ_(YXd=x*LZDvxoc+?*xnYD?NN|+W?Q#Ds`c1a=Km$ z{quDjSjvZ zJ`FR=hab_C38qnRAzy{&e=6c`3+asHf6#lD z3TxX5EXW#sdMsKMubW*^fZAL&mk^!t7w9kN&Cbq7WtXsz#2wc@1OhU+IuT(c-}ZE; zJz%u8%~vHD%RTOh+@O*%9^@A;-?*2w*`Cjs`*lB!YYVfAoX@n;y`Hxts!yNCiqEzphrC zrWr}8oE!1KUpJB>;{ceSR{^=WIFpw}XB3AC2m#dsl=C2Lw5f2eK0f-&XEUZw{?3zJ zVL*r7C-Ro8yw9U2<@(f#*xUHP^P3@O?Y#|KV_HTl-U1goHSbK+m9~xtFt_DN!&%}J z+V>j;7$Q(H6a29sd$Uhhh5j?OwaaeIamdmj8w6~;-0L03sE_@6q_|OE zhe*ZgY1S~Nhd=nm|7dns4BQ-i<{%0Kw%D4Q>c5pLrDx~MHQw$z%a_X1x^Uf}GZ(z( zqFBtH_BRM}BXu)0<3j=OdQw#EdevI3{AJLKu1Txw4p7bqMbI7UXXg2b_hIstnL2w> z8Y%;zz%O(SwI7?MrxtU z&IaI(W{{qK?gJEQZB7gOn_a%Y*vkYQ*Vm)p!sk??IBT7^P>)k&xq}Qvw?|zYO}DzR zgLEpiC3XJ-zJ5RT*vWz!xuO(~j{6c_r-1n2{4j2>d!CrrK6(%#Dwy>a%=Y%qF zvoG~TXl8!s(=+VmC>`NrW_F?MmWWU6!Cf)V)MgO=!JoThmCVTvN@;X2Z?Jo^USr#mK7)B1Y$ix~LoK2LI!D1ZbkFcVZLyXH`fqaM(d_78~q&&slD-7N?EDt@$QEjP3Gs@ z-}nKry^l%%RC+V|WGw;dI{)S3*9Um!gM#__i4?xH@E_hhA_^#Fnu%MXS@qjz@x#Fa znBPVPnoVkBYxS8cAKDMb65e<=L*8~7smNMM| za5R5sUf=mZtb8-}wmXGkwBf64zTZ@$kxc~Fni(MVPFzz$a!Z+~>FFs%|G|wnKT(mP zcE8>pRPC7k#vTHDdkiDs?kt2CeXc>XrR%%LPD@LkwTc9f8p|m!Lw<-=^iF2%cxm=U z#g`NOfb77YtJ!%SvLjT;S_V_EBuW^7dB0IEB)u9b=X!0zHc@ZFcr0G-Ke1rLj7giWwKcwimKTdN#b3K%)e3=E z_{{Dwd>f%2TZS1JXlj#1N-wq>vWh@VR|WJ9k=uo?$#&#@vEq5&McBu?HwAc^K_5P8 zma_g&PT*pd4VaSmy9n~LW?n0N_!r5lyvhk#ag@D4=_Q&h{lF;EIVcTsF@Ram!6KEK zvCpvHjK$3g2U@lbU}m@#%1-M$d_&~k3h(tnAi!&>=hcXy1 z;h4B^Y96s?K@;(fvqKFoyvvn@?D_J6G_VGm7lVko^am@0*y7zQG(#d1jPsAXkBp^a zjheMPa|@IEPm&0QhVvyiz!F!G+X=)rJ^@Ao;Lov$gb*%EJ(l_WN_+LTxwXg4VA3P7 z^X|Ql@2{Vv-sLkBoEwZRw@PcQ##@xXMD^5|%s$)T^-0PPm(M1UVm zU;iykB2|VgjY!rvq5Y$%a>pHiXuRR(8M`GU|9!IT;e`#u;Nq>*HP?FV5(|dC%x_T5 z)o-ZGM7CMDWZ_eYm5K0C;AZ+(e`d*-pYk`I;;vmYB0b}M|M4T9Skd6L*=NM7zz#j8 znjBK!t4H`s(uyU6HJ6aQDl;4QH5}tHafnPVB<13*r>hkeQ2%Cj>+#-JMKXD?+Am?t zTqSh;`ajn%vmyj3&xygTFLaZZ=~2t&;$?Oq z5(Y%~fosU^&r#0PGgSpK<^7v>8p9jE&=H%s4dfc$8D*c_V`UY?mD@ z++Jn9#ndatwsNiLG?-xyDiP#zn{OR7pG+ojo6i#N0-K*Y)vG0qJKha&fB?1 zMz0(sXsN`urwqPFY?O5fF>a$ZO73$QI&Yy1daz1? z_P>#P<~@PVru3;5*i!KW1OUJQ{h__mJ7H&aX5^0NKjw#`&Cdt;9V5^DV5WmQ*}C$Q zCa(j(7Jf31%p@LjhA;C5jm$vmcH^-=6EUg3F=o5;S=f8(FA}3QW(FaaUsEv$b03H+ zK{oA+vt>KjCiX--UA|78uX52w$^b-PxAw6hiGHG9!10}znUYV(L!N4s4G=JVb%tU8 zeHy##c+X0}av}TVh}q7cnO4-c>+J4Qf2*mwCa|pzM>Br$9=YMMXbsgeUv2WwlcT`( zLgVd*+7a22phE_H6!nsyw?wT92i&P1P&*YLXg+s>F~cw3UKKZlgYMtY_NK3roq4N? z7DET|@7D){h{KcP@@QlMh(g?#7K#o=1K-B6BO+qn>@62*-Xf1R#)TN*8Oi( z^mt-Bh%@u^21L*Q5kb7%vGUP&m_61_g+jrNN5~Zf>eF8%smmIKXqwBpRiw-=H8|;! zI1Mghv9BAtVdexmJ1t&v^unDTXW_M(5cbMnt&_PTG`Z)#HN1CaUGN@WZienmnRoR=TU!6x)9{fSI%smRG5=ji-13b=1& z0)laq%u8iz*Bv_0hqtv5p~8Si?4AJRb9mvSphzi#j&(nt!M$JMnIvRDZ+0%JuB6p* z?*{HT%7^zQu}|l4O>A<+x$!ppUF%#qSj|l0?71ci@969lWMGmECO>h~XftGisUJq) zy?Rlc-{xBy=8)|VW834kpNvGY(GIH-(cpvN_TJ1g-1kP%ZaahzJqUy~S1`vpI>khn zMN+4(ZJKV#W$!^dJp4xwQ2hdI`T?*t%b6@yx5nGg_dcWUPBo1k#%u?SI$`);TA3~k zB|Y{g#w^GYvDVdoZI2wT%u4J;YPd|>B-K9Af~L_V{4h+lrt`_0?6SzFc!Y9A__}zv zt?G{rSHUh}Zf=A_(-~UjPCit%BVYFx4{X>m+8KgV_Ls)#32k95Fz}RyF+`x;xcm25 zdpnvmRy~qnz=i|5zs2u;P{QDA7Oet=Pr$$9;;DqJnBq3HSmJRc*L?OX(I47dCY#Lfc!j0~bUEqz+?)H62j z3DG6vu*q=|?lxbYs>e#6l6?HzM{9_Jf&xLDEfNROf`867x5e=4(_O%IkIX~+H#v{P z6mB#^@9cbaDLxHot;b-hkaFvS_%&a*M0H|sQCV`Bf+ak|tbp2Aq^R&AMTHmK6oEt?#__Yp-C;5OHF;u=Ej z)GOx3c+pj$Cv0Mp)jzcm6SR77vtG~rz7Fv0MsJSF9bSIRaP?D~*KBe@g-CNi@rJ?L zb)^e-_jFm3UfA3=Kx*Z=#;FBgW&L|va2MJ($js!rHiP`UU|>i6lSkS9W_qs!V^y~@ zg|UF2^16LhmjA?_or8HkG?!FsDX8JSk=hAn2#xxXEbmXQ_Q!vRA z7S2#m2n!GU+3?>2;JB~`!^~-(DShDw0Hz)v_VDEBuYCz0$$;}?=d~_8-UPSJ^~=V} zq_Tz0J^y1cq(x&Jo`Au8#bf&!)hN%agB?!=D^CaX3`m)o#5X+Mb6E^j*>&koDKI3> zO6M?s_FM(hZSn)A*lKZ9D3y?v+@fdfKe^nbooY8mQBv-)uC9<@NXsPIQ#vygxo|r6 z*~!>QoDrmI`pl<88rrgc5VLldK=Dknz7z= z?p`pJ14#&6(K8Z9ix9@aoKH0o

U1T*o0n0|_RhpvqVp8)WF$Kxt(=;c5z58-;$k z^cRtCzT|I{HTpiLD^EuKBng!T6&eZoF@B7+95Y{+^-vOI-Fx_Y>u*}hy*G|D^DJb=Hv|4 z%J7cdM~gL)xL>+wS8SS_BX*eqD*L}8YXs5?enDEI%J18{hbAid&Y|+~B9AXNp7(*7nTNI>X0t6BQ%qhaS)yUtQy$!*< zCb5V3e;|#&lSi?q8gXK_MnHV4_U#^^)pS>@=qbP9%repLxjo<5(ew!8kc5u~=~X`i4GzPDZX2suG3~9@ zH`}+~#E$yagb>IN62_rl?_3Pfl%+!k4&SUhbT;q^sTAHIhuhAbJ7#a^t+#k`tSGNy z;bW(7vsw~{%^Jj)rn5$qLubF;Xl~9#W&oV?98wxL?6Z;R(^V&EE4s?*l8UWMn?^cc zzE+1W&Mpiuc#$(Xrk|uTMs>9QunjQD*j&oO?m0QdvtGanbu__>t+ja2t9^Ufnl(mur=EP>Tfmrt2#q&2$PWdYdufOB4T-!(?y>q={q;l%{V5k~-&10DpiT2;q z*mYbMjCqRXm8l<~l;Hb+`lc${=Ihd*7sflR(7=EnR1~Xguq`QsaQI96+>JyS(^O=` zaohXSGmn1idS>n1R-%Vh>k@e|q9!GJ=7KwCaLr5bj!rdNJL;o!x~AH+bT@+sVh6UP zrn8MuH$NDvCNYr)icnt{rToosCO3p?AM-90 z5HkJ4sl8Xey7E%mHUlkE+S`6o`t169Bh}qJ9p3uI7x$2kU2PL;-!ewiP{wB8_J^kl z&3o87D04fPOKp3={hnQhrig3^Y+~Uf@bk57(OYHTd9!SZ)QjPbkp}$1kdKON?x#g> zY;Hkn8Woz{0qASX-V}QuY$Ht?Y<-)~neN%!*$kEi&-0dhN9wGs^Zn)Fb$Dn)np9G- zBp&agfZ3V%l_i_`~2i5A3!k)x?smoae#lKJ(> z`L~elkm~8Inx^s`AAi~s*?)Wm)c`FVDK27U-{`w!Fg1;TQ>xt8^;(k)&)g}B5WS8w z7QpbA`1AjZ$>>LR6GS4tq)_+u^=k>6(!o3o_2T}MKlX_#mN5* zqM&_5Zf9n+F=GgE-0B@LcP50;`{jV7sE&%dOw39Y7}2$3&}N}`Mx)0)4}w)m*F9Ma zVK#gsd@5|#VAV{`iR!)6?|FY%o{|8SnJ_W{CWE3=6LyVyLgLztA*98!IFGq kB4oX&FY>?nvXRHYM%P-AS1b0k?#apibfc1%T~I5C8xG diff --git a/third_party/golden/wikimedia/Ghostscript_Tiger.png b/third_party/golden/wikimedia/Ghostscript_Tiger.png index 39281dbfbd122b2635621901008d11067e6b0fb5..f6575c7488dbff3dbdf95673a84625c190b6482a 100644 GIT binary patch literal 47211 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 literal 44515 zcmXt9V{l#H*KTavw(X>GW1Ed_8;u$@Zfx6DW81cEzvuVP{O?S1C;4#iIs2@=)}tMv zC@+Zsiwpbh+cyNMA7aYD`|y81(2&6IO3kV);0?rCSyJR%)g=B2@CUfFh?FWc@bZB+ z3IFzu_?wiNu&PJKd8T^?x?0mv_d=_88`Tkie;heaI4Lw~9(Zp6b_&P&X2kb1X&)rcwRt|*a&gopVSN$1%;!kvL{J4fjO5a@E+f`sjZ`YqN3BqN}YwL`H>^& zI{LBqz%TCKk&!DkKf#15^?GZ`!f2{Xa_Wj=PQCEr=kF6N7Nk*)Nq;CvncN@bzubMW z{g9Tna=ct!)uyGTr5>I#e=8zduD6B~4+&9Sm{-&`9X!GGHRhm&fULv~Ru56C7B62w zwquR^^XEr*U@$h@jTb8`A2J%+U3q8Z7V9q|=zSqDC3GIAeP{z8)|3Ib?p+Ig6!W`7 zIbMu}>Xu(zhYXbb{P;@frBzjCFLj0It960KVa_xRboq5nS*MUoJk>g-0WlFuCT6Cr zF8vl&t)G-_ZWq5L@_CM0{gIx7zx$cu^SXpH9s2f^9gK0iD}@4c($KK{T;q(PCHPY;txT!csxn-dZ6Sh2BsHe8-+!xqZYqF{QWmgJ=CyK z{QYD;ZnZtq;_=>*Q_8ADT(rTY6uo}}Y*~5kU%lO*pkGMWP=Og#su~*gmUEO&PZ!(4 zNP@)O6^9jvt*mSPm0)=zzh`okp})K3^q+bNjt5A2Ul& zC3J$|c`n2fJ?hw`K%p$_5{8$z-%1f$WcX-V#l-vuge_g3(-4W(pjZ=u>oH>Ywu%xS zSG>owUeCn4E2&YE!G_0lZ`V)2!+MhHzO80Ti{Eo?$AMe3(FKGmmhc~T_T+Lo)t}^K zx6P|NsK5p^JawkM7@>{9h`P3~;g3&t<}?_Ae^Svl%D=}>H{PAaX}S}6eTG6^;rBu} zdVThpiiF1LHEI z*H?vjsl)2q$OSi*#*{SRiF~?#U2e2DzoiEEp13%@A)q~bt>C`iUr1V6(Qf&@RbIU} zCQ#Ko%;eoURZF}J6Wf0G)kEOYccm$BCJ>ANY1sDPr;>-3^C<7+)J#se^E`konTnOR zKJ99HQJ%0^VjR!I0)=EFXnBw+mn1A+kc^C0WFis^efYUv=a;Vp>moCstNh)qBPQO9 z3r~R^SsGLocA88oOoGNi+>P6~POhV-DT70jz7kcZTU7wfOTs~mij22WNW-y3Tu>-) zFU{MG)$1Pu!{nY@JBm0;>`*ZE@0JZaaw(BgRj23cpMvk(zUtMQ5=kqg_a}3yg1)?G zim&*JRPv1-+itr^pq3DlPLIxK9QiAb6`QMJ4V9;$ zDIcSV1)I(6i5hF}vDn^Z@EOLZSrcK8QHviw+=YW;&OI2?*u-*zw6U)2E6pxY z;3^sTIAupfQwC?a7QPEtMxre+x}h&Sc#`MA)B4fWswf^!iOXq2%t4AfyEZ!j|J-tH zmNYtW#G-24u&Cjw<;z^IRL5_E#An1}Y=(-Z-gSx$&kH}hXK9w~XBhPmgK5;3la+trk3U$AR}p{sE_1x6O9h`X)bmmU+aV zqR-$kw2l2*jB}h-a>v(PJUp0TyKqhm&#?F_NSnq%xC67XPHK_pk6n(!Z$jaKu2RVE z8~ND&piWnxuJYsxYy=!7Tym{LhmZs^jL#{a3S(@A71D+l@mX0?ylqscK1LzHym9$Ax+bIs>7zF# zcBF}*x93_QUOE!9G{Yb)lPEl(K!y9awG6)e?44Ht-YPH<=cgEzho746XMO1-D*+emb`MB06M9EB8}0QCDcNVI)<&q%f>WW%FoZI zZZ_N126a&@eV-d~LjQNit*u%V$e5!PWE7N{%eT;fMBq-4z(^eGd)gdflDzX7QYM|} z=OvBF)%q!zP^xq9mF_%>&(2LT?iTk!;TEILJ5vU}8%=A1lR=16E>qCEaBD5kTy~t6 zQ`k#WTU_#yQBWBUqrzIH!>#fvfr5wmD$`y*JqV>!?mOxgBsDPck=K%|U=pzM9FbI5 zA!q}#{m+D;JCU0k4^=^0+URnrz_7Ozyl~SD4BYSZQ^p(zeZ+V*x7G>~y}AUbCjhKdXv> z$Km;zr}9Ady_@Why^t@~P?M(%tLA&m6o=+?pf z-2{^v?3!V2oAnQP%FOr&NrtFPtGp>om9tVSswYOqqC67j?=_u@G{l2Bd5f1neV!aH z@i2+vgE=I%I@5unQ^Bozg_XLdFMEPE0@k(`se^`@PRz@2i zAOGG@7Z9;mWpq+^aMX~@=J*Le*bV0M{Ew^v!%xOaGa*Aq`|9we@!;KOmE3b91Vwkf zcUU|XQeL(7`S{36{ovI((h&Pkk-2$prm-4hk-x?%U)OU$D$5F`geyy~IxKc0EG_Qj zhZa9-Vm4)iz4NJ7ob^wiSO-!UT5w_>5jpjSP(&77AtZOBmb5iUG3T`a3#U}JZ3d>WVV?^l6~0!BhU)oDMzo1H56CgRqbsXDQ9WckWHY{saqqv2AUC)i9GrTu6+-<q z{I`^-!*xuDimeaMuU2CqfwNv*{`!jHI*Bh&2$mk?&tv~Ygm$qrer_{i4Ln2Vqj)t2 z%|mnO$ZM@A85-|Jgx23Oe1o50y?*_L?leYl&e%|&-!oVxvZlocEwrIEmMEyi?+Z>hsx4&Twx1u7MK<_(1!AyvGebTeYZzuEI@jOm8C>gYv&N`Q)ic_o?461K0a zq^rArik&hxAn>$~cE1h);>H!Rb^Uh@)bO>7qT`ea_(hFxpr)8ij=(nkbd`e@I$HBM z34`6z;O{Nj9ickZ}JW&v@&x zNG4#vJJ)(ewYnfJcRIt_A`2SnB-J7R!yFB&mHct5sQ-~01f5A*us5r5 zxSZOQgPg8YR5B^P^n6!OU674>MU(l(zaeo~~sTxbFq}QpL;D@}h;Hn;Cz1vAP(+*ff%A z4^+>LG{Cx3zu8* z)NtmLSLo%d>_2V^yVq|C_qUHMLFLfUpf=NYz|EjVhB>3eDNg5dI|!U0zdemxA0s1j zo{txtCs@^(~63T@r)mv5TU)r0*;4Zu4<2*Z$5UWEh(R%OAKVd z*xtr+_C=Ygd${5=FkU@f#Q4?JksbdS+!)yk38US6veF zqq^-yKoY(*^*=SMQ`CG`6Qp)FrZKrKH9fXe8uf>xjHh!k1>jZawI{O}4-!iS@@{Pv z3ysQDcX&-c*};q!XZyXL7(5_;32V}0s&{=r`?9|TG+&gJ3C`JAeJIh?< z4eqOae@@r*W^3~;Qe{6>PzjqImKKknWI&{udX7h4rkfq?W9}Znus4;Rn>3DU&DS|* zOGr)XFCj(YsN}!OTS)mbs-G4b(+1aYZ}09(D=P~Py8V8Ig#pA*tJ#hKjY_`%0&!oF zU{*!5$!MWknWK>Bv)tv6!Q&-qhgI{{)d19~2hfY!1}#(lWgugt!p-+!=n@VOSe(^T znTB?BnF|%jBfk?gu`ukO;*Lht@ zSdA!vJ@=0jN_m+Xr2M|UpM64Kd3k!=Zu_o;%wlyp#nF$arn~sE-Zy5dbyz zBb&*a1gyQo!-9r!GnA8Th=}3mQl!7@Zon5QC=COn$rsnvAB+nQfys~7G%ik6CzWn$ z!K}0xWfF(CchD?tJ-10#XR@Nlhu<79lpJ5!sScAd^#l-{WP2 z)iQgtF`w$qXvN*v0tqht*gVkT#cGKES9MPLFL zhJaF-2y!@_$_$ITXo37m%G^&!X#mZUE*>{d{W?pm;I+9q$Q@Q~NJ)I9^`0IFL!)=MQSJy4J5?mTZ_YsB-=&0vc#zv;%Q|0v+w8Bl z7Mi@{TNIL;dRyX1I$8JV2$W1tdX5I@pgvB@_%uCJN?A<{&eu%opEh-?0^CMW`Al($ zgrp#ix{Cn(vQDF(p- zya~dsxj!2VUD?d>Zaqn=3tOV?qP1(X_tLnf~e+86&ZyBFze|blMk>;%*M< zZ(VH+!H6vSP@6~XRvu@?w3Gc1FxplXq_lCdoT$>$lO4 zP$f5j@7#aEhyGX($~uvWsX5H?$NU*y0N7a?B@`G-PmBzWke|D=hGIHO+tSQfw9 ziS=O4r`xzR&I)rY>*PuQv$f+_qvVHiHRU7pQN&C{SNGPM@&H%&-_lx+mjtik<5Xu~ zTDYf$+IK~P7mg}7jc6N~m608v*NG>1?Cb0qzO+4eIbz8e{GUg7Dy==s_xZ^>>+AQP zAPM>1`A!?MsL2vg*u7$~ z5^Fq<^ksQ5^kx%AWMhVMlmp5^ModNBR^l!&#bh8B(~K$})RyrdGAOx-0NLP%D08<~ z>84V(A=L>N;k5X3;Pu=EfjX|^jl2U$|OCrmRbcFN)H8fy<BKhgVexx?ZpSp){=p!EyKf*q45$AXxW=4vz_$V17&Bb$$!YnpgrqMlHXD z0o5w3n}GzNu7IS;FT@F`7Ko4NE6WZYAWET3_9Nf7f|{R!%i!y#?Y~SuNyt0u!&_BX z-m(ZM<*eswivd%ja1~ElMhOuFO|$|xMLUWU=c*f$Gloq(cO+{+->xIkw!T(9BuOUd zOKuLkjqmf|mrH+W$7h?WxEZwZbyMNRB5yc1wCNu^8`HujA0m^khQH1_O5|y=?Gj=! z9kTW`7Gb?9YJ#HLd=>X=7j@wsvcg`R8Lo+uFnEw^roO9pAVItIju=NISmW4w>A6b# zZYK1EEI^wKfbew!4xhSu&H{*&c*LLM_?h1uNE-f{IEKr9a>wGPV-x#_1rdwtib#@r z>BaDNa;44NQTOeAw^((lqrck;BdW7mVZH2p(pRt6N9b9z?FGk9>`kM5u*mTZ@bM5Ha;d083KJCND_H;jh(X}W}ZL2Lla-e ze7A$y?}?efPxVGJ_|pBy1!Z;pgB4&BfEaR4Q};GuFzt@SOdSJCgaU=?#O^PiS~KOE^Hq!`>pxfDs_|*=S75??I6WWK6$I(G|an ztS08<bCplkB2+4nNYZ&$Wi;a?|?z1 zAUBj_xnk#6F*|Z+-MK6CSE5%3O+}lWx=>lzDeUtXQX8S(k_>Qr#MJMtbLT7dt!Gv3 zB^B`OPos5F3swh3>2|QJ?E$3ps5lU`&NvSk#fr2L^6GrPJA|Cg<0Xs|-O{J#dA&5Z zo5`n`Nq$O?$&hU&sjl+H>V~e;!q$2Or7m?RCSZNMzfg)0KIB!%7U%^G2QQO-JAYK2 z;Pe6_FbnfWfKL2K^#d1-2B*ie&+I8(d>qP!fdi??0cEB#?PIm+Q`5vU`cD&=QM;X! zNrG-ZM5ohvnnQkWMBC92S$|8+pF5kp74emrV>=h*h;6t-md3tO!Xr>i#Sp46HeyPd zkqcoA_i_tt)+!iK^64g$Zk)HbEz?bIAtF-JVS(6C@?t3h_~M#||Kb*`C@3i*i`g3R z1r2+?xt%Yg+;%K0M*1F+{`Pz3Qr97%D(_q@8EmO_-01Uk(8Na}dFKLDZCD)MS$yrJ zo?E`U_wdTq)1T*IRKb{4XaP{615VCg$CyU~N(cSBiGU#2i~Z}bAGg`gfGY+GUA~1H zXfsmy;b2#saJ7&Y)z2&bnDnCV*K!_2e|LP7tD=Q_xMtRa(%5P2wEdsLl}ASz3GZ(S zQ$9nV{M3}+&8q4neNt4W&Vf z^q$5Pv4bSLY0+U_cnRvwCU!@tvI`m-62YJlpQCALXh?XzG zaUsNA?PAm*sjjo{Y=Lc-t3-2*ji;*+$yxFPUIR)s#9mB2D!IHZBthpghdmsdT6(i1 zfwml5^(kT&#-a?V-sJ%jQqPeAcHkv8<5h3KD0RXN*8e?`aEU)a2h-!a7m9|O+HkAO zSF=(*ChPtQ+u+aieP7bw4gPyM77ZVVpcMa-?}g|dZ)xb8X@AFu_^enmtL#8Gf1m#+ zj@-Xdc|3%{x?!!B)OmeNZ7Hbwh0unm*Nj4a|5>yMutFB2e(2NF)0V5Qx8c#zJnN;Z z{(*s;74z&`_bdIuXuKo$i4FIyiI1nPsTRk*mYYGmm-G6mv`h>|Di?|D1*l4iumy^j zJW$-9u2LWyl^KK)L+Xj4=hPVRk%)gw8(-{aErau5OxKeG^+MbTb(BUqoE2($n+X;8 zL~X|1P>LlFJFQi45^Q04>|OvWcLX`r96L{klRI{>Az6ilyX;Z*tcNoENs!)J;7pqJ z7ZIL-H*uxjTt!Vy99WZ)i3x;b*0p2syKvT6M!KJKQgnbH0Z`BJjI%lHG>pM!s52hr zll|mRrF9uzMh#;BCAZF|!FQ;d#zl>cXSNbG|hBQz*lF#Dm z&y@Spt_>#G?M~CFx_4p*OfxmqzN?9tWlM+kar9a^Afo_eX)l@SmZrqk``7&?Dc+tC z??B}pT=*=V=vMfav4y755c$RpNW4dR^+w*Im`p}AeG z4vaB%j~B_MV>26m^L=}Kh@gzNXlUqYtwpUD-4Cga@Nu<e$I*2I;WB0!-fP;8b#L^(u-L9Hc*ZLXPBB8lX5^Nz&%YzAEk9`}@efPzT~2$p(z~zHJ_O=AASe|bv440m0B?wv^Yt@#r`@#HAPJFe4vs_*1DA$ zbFCEFIrDX8=l*yI^pA<6%1wd>4cT4@lW^gD@m$vF15kvCSSjEZ?vHi4GN1oxp?Y-q9)sW*zioFuZNk+UB_)M08fGRXVK~VCjFL#m zh?XuqJYnh8$>X5Cq%h-ps6_9AgGkpwq{cO$rSbICMb%b2{sBlyfEoqheM^n3Hi^RR zRF(+pHEal%g4vNhI+-|a#R}f!%H47#ed{}1?Y^tf?=k0_VoP+FJ<;)v)=R7=!^oqf zquf5v%w!T#->$WO)uFkpPgDJd?u-{K^&)IzpER#)Y$fj+V{x9tdU|r8?AM{N!Hl&L1^Ef{ibW^)NS{);D;2&KzyV}OJ2mkqUZSZ6! zAC#_;+qov8*KuyZ9&9FxxGF1eWki7k2NKc~l|_R3&KHznMhcd z@G-!$qfUmcmA^Q6Blzp+{-T181G+r?$Zs)pQN9hpD2nMd?6Ki|OR7m_GmlZ=R4-Lc zOiXk*t89MN7`Okoq_+9QSqF_V*jc!87U zJ?K?{4o9AVne)V@cs-wU~EopI? za_ioX^r8yRABw|^YPC*}2@J2ft3g{fD@0n!D>X(aVNDgJSI;Qq)(lu`ONs_p8~77< zaqgGvBeR7vAb;ma5ZJXuZ5ZtZ!{jNhXAmsMb=5`(2%>;(8V86xH>=MkX7-hXr|}-| zx8U*%Et=j9fmz;GsjExfI3{KVzrz!!_5P?==}H+Hkur5XlRj7*2XLr7K3|SJZw9bLS8w-rcmF=E99j5lNn5Fr5VABt8&6aF;En7eYo+Q; z#SY;us~s~uJ{AYg0K|EgMjekGL&RpJ z{Y@CyL_ay%_@6l$sPc2Ue8_rew|FBnxaSY`i# zh;CWW#N0h@1MAo$Z*`y!zdA$)`B%XF<{^Mf7VUN|`m-SikkK&TwWUIFwvxcP*>yyk zMkdpcvf;G8<#D`I!kFx|PdObx%#mH&#&FA^K&8F{@UN(1&(EzLg$RRNES*#c70i;8S95fqVP(V)Td#@CO z&+`vhJA?qC?f?`bu643m==mvrKKR z_Q?LSWB~pwZOYmRg`cAaJoVgsmooz8>4vT3>6xY!*DW7E^|P0W2u-(k0@ockR3a}t z;X>2n>D(xMp7@dyYP;?aHvphFZ~5^-27>@|tTaL2RI?I&*n(2ux2-&xN|NdiVc|}k zePjez+4Efvk|Emnh|f?nWm5R4R$D zgJJ7ew1;7LuNtpBI$1Ck?Ec{`BU#CZyL_4BToKAuEp-DIfrMGS7=8wWH7jcpT?J49Lc8m z@1m}*@a$T8pRSgdHUEpXNW|brXjhue7DydGc-eK_Nc{Wv51YdZJ%LKW?gN4*kvcz~ z<=4>9TGeM5Z9uEN-Y=u1D$r+Wpiyf<@+v=5qyhhQlfsX!gl?de2V8{<2F=yU{vu_DqGxv5L(z&aD^8Uwdjp$G zdx?Ih_Kjs5&d2kW;HF1xd0X(Lq$E{U)g0y0|G0~0oe2zL7#I+Q^77)%$Lim4QE-D{N@)8IQdEq1ywwOBGtd z>gA^I&o{s)Gn|PX_$*2aS+cuTU*V@RVvro$h#I|Mtp}zOEjyhfsP}A zyj5TQcrIR2Vc!W(iu{y7hO|YxHTh1*LC6(+6GVB!N=l$FOyEPez@chaYyk3SqE*zZ zE92s%VTFrNt!j1d#utW2kS7|3*grIcMtF%~Yh+|JJUslp;?XVvC;?!S0n7aERO~<5 z?DSQ`-5s5UUiFwT5Up*RZfX|07NMzv?%)IHJO61q8QhLR0Cd7UI^JmKay}gIwc%9J z&{SfCJ58neIvu{60kr_Tc3}|M!(k08}A_al!)lo zMPD=e?Nq{_c*typvFFO2kW7hV zw&I`acrtCjlK=u_;e9(jI}XIqpjM4(w+T>xDDcu&`R{4NqoTyBm;Upxfdc3QWHWnRo0Kt^~zUVy;6H12Lvqqlr3!>hpzQGbC3Vc z*Hdx#+vwiz|+bA;?#jZrMebxZmmZ=d+CeRW0&em9Q0F*1QHMevx z)<{=UDYU#)VW7R1r)b)vr4hA%O?&$Fek6p$Vg#O|=cYA%1MK$t618S4bQRO#iQ&_!zbXMEq?rTEqi?-?jAf2#qGug%ZmMlfqeCj%^NcD3 zb~e12;+@h3IpE(vk**IvGVPTwI3-^nESf_n#~-ky4~5GfVk z>FR0#Ordorra)KV1N6pgoHT!%>3Q_g;U9c!7miwEQ+F(CI8terh>#wIQ<4)nTg z!CXaZY9=PhT*aIj3y1cN7Try`jFgn2!-@3&!u0?iBID#t24(=W=_qJKE{J1eyxhyY7qqY29&c! zemo(<`sXArTcrPhu+9+{vGnyp7O&kgft2(w-kbnE?`bWq!BNj@rz_|BHJ=Il(C_kx z=aj`YoZApT^5E8XCjLSi3<0?lYVMk75DmBdJ1F_@Iil~x6ewY zWh^59tw5)AB95FQgtdG;u7OQzsH-b0Dh3ckLkIO_33v~WjTr-p!0@~uN0XT_NJx_L zgH~f%HhGF6kt3&${YNkHuxps}g>dqMz zZmj<94DRp|J4IbeJ^-`;Jg21AWX#SdTRnT-k=XO)y1+ouux3AyZW2(Qx({!5=|B|@ z#tO!W8VLbmWNQ64#!RM`Upswacb`EEy8I-Vl@gId3~^GBd<=F`Goy2TokH5O%hgX7 zdE|j(nD@G_t{e~$5G}flU0*wVZfe~U(i$K%GjiFMR`hDLoc^8xK^c?+c{kj-`*qx}(RzAzfT%KtpR+Dv$}e`b!#Pu~FA*Is*=v+))+K$&)n(e#6~{O3^< zzl$u4;?Bjy7u8mF7z1+KrntC|k1?;MlCAS)h;@>Wb4}J&tY*v6uBK66A`n2_TvqI@ zLHzl5l4YyVxL`b4{A#9r%P{+)hT=W@jQE?Yt1I;>ETC-eV47lbSa09z#iRxg-IeG+ zfh1J51+8Cjx>Z*X{6t%69uIe2lKz+Hmr1xnLLx;BMH|VO5()I-#R{!HGG)gL!@*I(84`gn*+2YkAe zt&V7TcdpwgS3`S||GL>}%=C#H4jat`Ld)cb=0oJOBmgAhUbQ9Au`<_Oau5;K(MCZFvGmdytp%O7AR%Xhy=C3+75{kQ6aBl* z3OTj)7c~+jMux*wj)V0_QxK-^JI1o$F^|_;f99jBVh_V*zt^u%CRR~X`dJFz5 z>2sT}UGqF@r;Em=*+OS?H~P1z%?N3mrte24fScRi#dzykZ`_wCb}A<(L2*6H;Tyr_ zwe);4*|Vy-f$Hkx;j4{SEExUh@_dnPW}(t{J|j(4&)G~U)CdGOxqS7%FU^r^4QWPa zmwN4VwPCK!HDchPz{XU3;fLivn19$J|LAp$;%))rkt%NzPR3h5iteKe=65kfZR}FH zIMrEiWBi$QJ^zYdb&ukGwS+}wX6Gx@hX3GxBJ{in6hT%jd2dYyB+)#US5K~ z>UxlDFt!9Rz>(u4us%XYh}&Z(Xfy}fhE$`aR~-D?K>;xh=)vpC&d3=})!?FDiJ`ph&GGOa2vi2^8NK;ryNYxWqx6JLM^IR{YmvjJ0{iD% z8>cOIBE;r+((BO9T7s07pwZI3K-|sK!-JoUFTLd}p1X~s+_tg0zxQB@@o;F$Aa`hl zLbHtaWLgMk;Kkz45+XG9_X`DLphu7YWdSQbM31nfOe{ugQE6vSjZOc;Bj%JE13a@U z_j8~_5tEVzmG&`-y?%;Y{RW$p7-O(AtD;A^*4t0czGTT$&HF8Dwq6(vQqu67yx%-e zQS5g4*6FjYCj4Yf8vAKSs;u&JMAa;;|Hds`Yr?y;`B!tbWosf`PsoTI#s&yyrp@EwQbHndC~OjpiaeWiKl)Zw0{ha)&3I-s_8V zJszPH8RrO}+rH|Ti(ZP_*eG$S62z2XnYhnOjrxtU&9_Tl62VqQMgT;C&6jJ$w4 z)xQl721BVf{23ele3+Bko66vv?pF%=&lT1{Ejiu`Nhq_y$x@QcR|R3bn<5xs&x)oG z4OYY!2(E5eZg2iS`hSOq6H`)#mX(#&I~}Fx8H*lbx$|tyy#euYem2Uu%Lr`=XigKH zQH6QZ#$ums&miS|QOC64`T2QfuX_tl+g0$MnGFPV!Urrc3HfLwVnpxYVN>5C5@^so z>N>Lrt52UH0(!kR^l0Vpu)_EV@^QGfxC(+V0!MlyTb89XwM5h&V4i#xa0t%X2 zg_fQ{rBq1gJ9tP^JH?Omg>OoVp!UArf0XY{rZcGK&-_VD6!Y}t0S-|3sR?KYi{F49+QoSWaps+Pso_)t_~Xq!#dE6y$8V#!TeJ7_GU#W3#>g$Xt5B z7W3U>`D+9sD8;Yg3oR^?qD=W3Oy16!Ds#{V0+PHRLDm1~PfhJqga$HLp@?iM535Bx zmDX-3Ia1vCpF|dDs#MSqvtjAy-61E->%Sv|=jG>@mY0(OabdZ1^?33{27~?wmP)1p zeO(2wyug<6rjgDgw0P>hx^_qQmJ(i9(6)~szFtg%pU=j(x9`@VkuSLVT^Hb;pL(T5_ zOBh@zTpqBE#gBK}XbQIzY0<(<%gcBhG;Izk1d_tpj8}_Rs-R>#x#hx5kVvsMX+s^-(z!M=;+|%*Yp$0- zOqW{JeovFmH@W7}_(+Y0a>Y^&4MK1%63-1MZq6v=oQTd7U2mE-LpUFtVlH*sgw{{e- z-KhheVI`x8hDH?r7Km`ZsN$KT6+AV(()w%j$-B!oHww`eH*&+F}8 zm(%%(npYp2x2}P#Zai~K#=5n@ZzT{U-yY;9nL4RxQO4{fYj zt;c%y=%lqgyv>HyH!j41qd+qWZw{@x45t&eq<>~-l?|4EjhOs1v}i5+rC(j#)PyM& zugxH}RjWev?b1MdyvGG>Ne^2%TNMn@W@=ZWrO{_F7mzV4sVa5W=&oOcL*w%xf8R1B zs&Ut7um8==LG2+67KYHKm~Zb0S)P~v!6~eYJVH{gfXbpp@Ymx`&aWRhku(O(nv=}D z;;LPA)r{R!=+v7|bc-hf!GmMAcqsSq*!-yVvLHfuEK2bNY(hBJAHzT5e^E!Y zh*6=nO9JN^qqCiB7a4Dte=BchW;kv3Tjp1W=jD+aj4T^kID-)=p`(b$g@!@`+8kgr zfbhUgC~0X$%vjj4+(30;=6F-W@0>9Vy~ms_fG)Ysvgw|DM@Dxcii@Zts93l_9eF8C z{%1rdZYrPnyTB(EM(KaNx;%&tdtber^zx>CssM=AOhzT?XV$bMb^$>6L%cDwiJ_10hOh$E?&dH zH;Kb~(E)IQyI(4Fj>r}hcdHo0ST&{<-Ga1r2+XTQk|{P{M#hWVb*d6vDXY#?{}ub= zAO-~xj}glZ*FnesqW5~XdV{%qdrb*A0|xZ|42t>>1rzb1F|K;8tRa5b4K^pI{h_2*r0@su;l#5CJU()-83T`gjKQbr?G|T&v z#~{&O$HDjN2VoccBvZA1rD{BSN(5~u(yCvAVu8z@okXwoydrH9aNU6X1bWDZ4L?t~ z8Z@sMZBf;uk{V{hC|NO?-&KZPUk{>%8Hd7L((ry#4(c~)?~gsq=imBUN8<60j7K=R zGc#ZVQ9|g0qFo+Rf>wbDWeCA{HN^`Lo-^f#{$S(!?Xe8WP)1UG)!Yg2b*gG=C`3d= z?9obv$|Pf~gt5iq@?gyGr)Mt?OA_&Pn5^~9fvV{Uok}u8ek1efI^puxncVp5SUOxu zN=i&Km5~v(8h@ux7i>vG4HbdY%h<^xR?-Lt6&3$-0xum6=X-`7aNO0v3K}bnM_#FS znOZZiCxc6bnh5Sb)t2wv$Ye-^9JI5b+MbRlW7)Fz@7(pbUy#(dVQ2Z-uz_H4tG}kr zwEi`22rdghj&1Xp61f|=mRRn5jw-Ehw+0|KOBbRl-7k@ll94GDKYq6=5&lUpZuxt_ zm=VMn9c2gR@2PZc+E~qMPtiZdf@-E08B#RjvFb<6Y}sV+Pny|;+1MfTzoT<4K}Pzi>tr{of$f2 z!PcI_LKZ;ftWOyHG=WV5ZIp=6E*F8`t>N$L&L|X0t@X@t2Q3KoP8vo0NQjWV_pe=0 zNAl#5XKcTemreC8efK1JOjrw6$BHw>(L4ItkI)*pJHQra+nA`e-qBebFGp3$ErKi^ zq%;8d%E6QzBhm~-g!xjqtPpBq_%ZowitMU}$DTZCiEuu9Szf0!S-y`eId|sf<_YQP zk@RCf2(bud5VBsS$y3lqOvTYDz#B0YYELzsiEUO_kFjRI$ zB!@L83%>RAI1TIp;Dcet2>y4w5eA>qW>U zqcLP^h{);As!b58T6~0)j)XM?xDSxd;;F?Nl@XCl(f$VaE;0L z;>k@9mUOfYDEJWs=e02?!$1=9U3Da3f1vL#I2|@b&N?wYR1s(OtZe$QVsmW61qmbk zA5B*Ql+_lkMFA-hX%LWZL0Y6cq`Q$uq(M5abeDv53rIqf;sS5b^=2J5^{`@Izy#uNPI=7!JbY9&}x zHAV6%O(pR_F^3*4+;s0v-U_6* z4{ypmOpl!D!Ng1ak2aqWMPb1?;z+rUneveU*m-*P&S(ZW^~wn|l_qnUaZXN7kORg3 zoc5hdzHyWF^%XL1zhWGVk9Jj3G2!`ivHMTm^)LA>mA(Xqe51{m59F7>G#Pb2QdVY3 zgnnYIJcfmWo6qw+<3(Qn3GoT_i}EmeI!cV(PZSi{l8SY)hs;lSCWIrHeRN#!j&h)m zwR{MR<@>z6bN9QA1up9dAGWLXgL$^SDCr{UU&I`P2H)|9+k4V@-ZV1*{IO!ToYq87 zr~0yJCo6w_pMI{Fui>BfY(QDVBOy}?r>>0=oeZhLp<#}U8-nQmm{)GpdZsF~%Q*S! zBWI0wlTPMZJW=_9GrIm6Au21iI5jn=^H#oNnOREYokOm~hdJ ze!(lmAISECh`@rs@jALzgO7hXt)DYp{ts5vDb?l9YhoY1$y!`ZZRBqoN24PnIrz9B zQi12K!Azi4TBm4SMJopd--I`v#tk!jSjNuosZx>pBktJJEceRCl4%ub1yL&aHRt9i zNm3`rZF!#Vg~{#8_V06aG#C1mMF>=X;uPqAOuD(wf0nAR-AZcHnwaEOTz0Ioi1YPH zVmvJl3P~k{sD#8FW6_U8_n1bRncoCzcz(?beuw_bY1`@e<@(q^5z38!?y2YFDe~SZ z>B1Vampw>s$E1&@UolwxdWrA*&;70igMOyEew+nK2foz!etP(0-pI7~EyW8>ScY5Z ztf*X@Ps5~H0+=xBMnkN_#cI3r9dC8f;?rKA_Va>nz~sGCKK z<|6v4of8qN3H)WI{@lDn?svSbq0;_w@15Q^*&gHjo%i~Fi~SP3LnQbs?_Zw*Vs;%scH*4l&%&=iB^icf7 z=e10sjcnMs%{*tt28?bF?DPT+?>eqCT=#Zt4`f<)zL=Aj=H~P%dPYBCLd!$b%Eu^D z39Ypg1)6mj6>R5N=j z;`fiotfIY6;z(IpnSq6+bYgM$>>o#}0@1gv7Oydninc>sOQVFCcGgf)PqvC`GUgo? zJzBcpOvo}pwpU|l;RWPl8q5{oAjD-rsEfft6EiKcUX}vkcW3N_fTEa*v zehTq`k6NX=2V-4RhcS2KO?Lq}G1OAeua;!(yVW^1FV`O89_pK5;Z}d(G)$ z>cosnSIW=TCX7dXQHit}JFE-Wm+hPc>-*{&kBZ|*B=`L6%N|NnRmpOcRwQmc0?oHb zw3Sf<_f;oF6c#Gxk==a;?A|g{JjUzob7hfvDfpwQ0Pl7#S;8h3$>4T8^vm(zUS!g| zz9{8&>B|V-VAEjE1>rF}PDv>fmpo>At!%Ml1Ra}b-`!|3xE-PyY1a$+C9lqrHOoBA& z#j39)4oH60xtB6lK|*8QcjE4@c9x$7SD2 zWS4`)!Az3$lrV`7)$D@lyS&T(dFx;Ve!5Q*JYr6p&f|Lj1t8@ zc`p0>)%om=@%i5d92n+@$<^nM8fOdxex_CVy+}s+v5*@W4^hJC*`pBDGPk>`|d!?CNE*xj3SdrkuDY8MBr67 zxe(Y`O8EIoc~Vv7_eUd!>I!UB+O270=FdBel{iU>@8YI1Mdp3k7ybU(wHWH4{4Q$w z`FV33&5LC;e|?2aFtgcsa%uJi#cTSZ&4Xg@oL|(R>iYEVS-XbGU5}b$OJvX8_cui8 z`2Mr+0YP!C^zmq>suTmwCUq(f?8<_oB6WRlw&a7w+nbcpd>QwB?60{Jp__~C{^=zC zfDGZ|uvojwQEUUt}mTz_XPiMULZKlC;D&C2h?$?dhOLxw1LdDg7mX%}lF5M#_6I7AZv;W!^ z=($Hz(b4eF#eQJlg?Z>l)$)2YXO~LkUA_kqbTsu`&AEK9h@BrS;0cucTV<2X#%x{q zFQ+;PSrQ99-1epD{M+Z3Q7_S(ZT3^LI$KZjRWM)Yql}UT&zRmXZ`0j*(!Mwhi*%Ir zS(DXp7A9_7oA1B+H!TWj+$9p7Nc*ermEB}Te^nR`Kw5=(W-s!iQEQ2Ou3)sZ7>}#^ z=i`J7AT1HUtCkpO^#)cA)ik0Z@TU+{}g?#?g z84V5bzWEu?%lGFt@{CtLNHuC$g2!Xh_8+`4lY*PBF1u{FeNu%i z>f}94lAm8RMEN(_Teo42;l^uH1p@AMpH{my7rBAL`=o8;=zc-!+029z+*JO zyiuxEZVC*yJXg-?GlvDiEHLfz_MZC)3tu0rL-5Z#%k1zMG^Peb8kYB&Uy}LhldV@9 zklIAxpddxEWCM&-D5w4s$45BZz}Psp-(0+Of?5tYftG5(S<--(?2$wB%s{n*q9RNO z^y2e2q$amZrT*$w$5dY|POvf(!*g&Mhdvc-O47~C(3({nesNkbO7uNir! zkZ97`ZKqw*tpr*o4qV;jbdt?#R&_(eXr-b^l?Gr+_%HrZ#R$36plgNatq>fOr^GDc z{XQ$d*!)4-Y`oydl~j*|C0owv<7+PxATRk-d|FXAL11V!VJ&Wff`TpZMTNjtL)+jU zdu#{qrXH@$d}sLCI!$9~oaPJ8y-U8NP+ry6U1Q)|2A`}u=Lz@4*oknsPCW~FyViH2 zc`nGNG$A+cO^1N`DhxLm_km0tffW&mr-5@DhUDv1zD*QH%F*nf}@ zK+ZhyGi%?%%F1OzQ@hG~l-kJu`Xr2;GYU?VBRDY*K|x;abK!itw>S(BdiKUtSKN7G zzYEVSOtq!>2$}yqM|#u4I)$cpHOyL+I5|~SkJ=Y2i*-!?iIr>RPwo)#*~7TRmhuvv z0wdtR37bM_DOK?amR=WEZv4hP+R7^a*wz_+`6o~>LsRbS6WUg9@fMbQ;uRZ*3B5Ijp&Hi{Xq3kV&Ea*qdB+I29z4&|R z!|dnvWOP+>TSp*r!4_D3iXw^gXi&-PYRk9HYr|98+P^4w zQ!-snU0hKy`j1-+2Wd3MJ-)dmMjSNC0Z!6rY1Ix&e0m z4*!zB4->8nWV?sUC}qHkjLS%^SQ1x>Udt5o(dADAJc#1 z*lU!B8o5czgrb#Wuhe!%OL&TTE^8=g2m<6KMy5$N%2J9&YDr#R-m%eQleR9CI^?6q zZYMXqd?iT7Aa36BotpHe((jVKE_Lnh-6s^5rvdkM9nachh26hVzi#d;#=pSi3kqGyW z`cJRdSuuZ=z`U}yzqEcqX@V9Y>f}^4=CTjP&0?<6X}8z@znqrj{OOB7m)qpEnhdGu z-#Bq`^^88FqzuqK#tI=6lB;H2Is13;?;7+IYagLQG1tXz`X%}(!ZFA3jPEvg_2m8* zzaUAbs)SuhWWpcjX2XTlu5_1Y{8$AKuJQ%Kuo9xQ%DZ!ZnU1Hcyum_aCZMFGS#q0D z+4}TR$R4{It2#=owCfX3-YBUAH(DK=wP?erox-%4m; zG$X02=;k{;nG3VJCA}hOYMh(!2tcCM6~~*6K7W(FR&?EaF&vTPb37^oO1|zM7It3hcJRbx)^pWJ2Ufg+M9}{6l1@w5sxH!sn@Sx zw}_v2VzMK;k$V31x=Evzc$t|>g)yv-JF{+oO{YGa_+0h4%()KdY1No(vVYm{SFlZ^MsxebU5-kmB7W`M8K2hi4FGYw_ido#vYPT8r zHKTdHhdr$~Be+OgvDG(|%v0noqZjb1!At6ov96^iEeo?`2pEmfa*(S0wd~xG^n)f} z{dE}c%xB_1#R|NVfdn1qG8W;|+%HsgGtf|35<1?w{pKMiALag|7qcn*&2bA$BYeK& zRiV>A&T-9Y>sqf`%loLA==mMtc0aClyba|pnu(ltjXOR`oD}oud7W$rYn4jD`98tZ zi68s+aT^_-(EEmzHVI8l&Cn-bMIv@*8@L=6zF>P-u@Yjs&pF*MDfwRj!tk+VvIP|O zp8t^U&5)&}ruKuCX<_|?dXbXTB8Z+nK8WH^w|euzQEE1_rd^kId_Tu)J=N;P_^CP$ z^0-ai^6A?q18!bk=1xeMIJod36S-n}`$m|SM+iI6FcLW|PgL>sy#!iSc+sQptZS*#%Fs|B=N(p4liC(XVb{_#R2N~#GF1CjvJQm(C*jazU!Bh} zgQHL%my??RNYQH8u9lgd>DrkU-LRPd3h%O3%v#{2po;dsp#nz7+_g0t<@O+&7hd&3 z#M~MuR?0k@XFJZ7C;zV~lLCe2*isq8@5YN)L}24vOV+m+D^x@1Rp**q4m!&_p>j=oIG(Y@1M#o!y!F&e55I?@a*6x$tKIlX=95s--z&M|erI+o<*I$S z=)>;b)*gJH!s9=PSgb_8iv%GIOl)lH`LV*w5G_e2gwiR zUBjPMzv{S)=tN9yYG~zb=bMwD)@5d3{wd>jUX^XTSWkCj`B_j<;COkwh54dEzA&%3 z`31Efp){z(guIT!iq9tSL9)Jq=&y@0vJ@W`SDG)5vV!h!X1&qvDQWwnvY}z-vWo-h z>q%?wP1hHNA3);Ty&aXSh5xLZA%|lp`~fOsNu^||cD`1q7Hy58|1b6N_;L>OuypPh z8T2yN4I`-%1%mK=-(U$vd0_?&{g=Z-S$u+~CuHof5Y3KbzJC75T){64?~O4AN?5IQ znHSflV%Q6=y#AP+25R`N6^i6Y8jdR}Y=60NGo>d1!+SFM6HA}iWb7ivK6j69+K3+h zD|Yv^-ar5RBI7&|>622ZmZ;r~rmPX)_A+b6NmE$NbMwge=vBDvTe#;(33LW-(-sIC zb6EIalx~eBXy9T9TgCFFqnD?u%*u>f(-4lb28Tu7$_&N`1JAW2gx$$iMOEdq-7GIu zjqXpHrH#j9FZIdK)>4cQp+&3)Oc`6-=pkyL5BOlNwv_#CPE)&c~(aFVE0 z5zJ^FjFPs*nV&NJo_Tj#bLe&)skD{$lrt--XerCl!#STKg?2Gttsx>2<-ZaTGyNcP!+cP!t6M_^CS>B~TR28Q>Une(4+ zvXhg4Q4gAf<)}=jD$ne_17`J)5IEIGa>PKY-teMqLR7qw$7R!i6AT}rUGFArq8)cp z?;-(QL>P%uIuS8y+qM1-5ADC1KcZ_2J%rgI9XVaEp5=0FS4lD8T187gjfl7}=TyUc zp7qPb{+MaR^8jD(0L$A4O~^oXV+(ht7Wgb{kauPCFK-+RX0nwV$!IwzykN$A;>< zk4Yu>hA}fIz3%cln%5pc1Vy!9pFV~|ob0*de_*3Hgn4dsWWU!d8=sJ{8dkQJ$lgpH z3*Wpe-eW%d0_AMsL1A_#rlrCZBbzgCH8nL4Sg?THELHknziD~24}oH* zxq{GqQ8BFti+?B~mp|%wC9U>&Kh<>faTMsSpntp=Fuv)mFl^BQON*|qE_5cixVRsl znFK7yIy`j#8o64LU)7dy*vWNuIcvh!?uyoQ!g;j5*aKNg1GTSzJ|m6(e-*n7g=f&k z(ME&*=SsRS@HC!&;shrTky6q7e|zo5RF|Hu2uph}h>WRw^vbosYCBWXK-Q0!OdAd| zw;0IujDU22T92S^QxiD;T)_i9Z8ckOXEt7}`jp~qROX4(PPrX}b#Q;R9Tg7RXPXIT zC?*rz9|%#ttvNHrJBeQ8IZ{YGBi0yaQN>Rx_I@7t`Oh^<7)7|fdWFO@DXNKNRo_>S zHP@0f2sNKMUda~pkkTqk6fb&wy{|?oiKJR0e$j7Zw`np#D!x6Udm_(0E#`i@_gU5M zGo$~c_g#ey&S*$;Yq%8cHzGO_@eRuv3mRw1zjsg;K}X6u{{6)dRdnD@pyy^{WnG1l zMlyf&w_6Ls*Y=)X(dG=b7F|~y`yAcF&^+^pxLIwSwo0E}!+a0e+Ytg0IRyn;u)xCx zSJ%+^7R|TtzketzO9{3GFtM%)%O*$yc@6IfGN5Efe=27Q%2`;@p`)YIGBB`klzpr> zfBB|>bzuD0FIdgkZhH%Z(4h{%*hp~FoZoml^9CxoVrjOOxw#|Q94zfE+81MuDjhi7 z*WsI4$7f98gG3lQi3}yHbdD4-F@XQ-SSwP8n`^A})2BF#RB(gQiL}xMl^)9_6nNAi zi+#1`R$Gzna$LS+eNy~%RF;%{J+WfEImSehlUgrNoJUwwZ^Sb`&<_nYZjCaa7*+KF z>C-$te>bboD$60(q4!$*-{myqaO#LzNn6xs^GqowPVzc-J>ZMW$e3HVVcAr$7C57y zQh_xbJXFZ1&c0LpS|dJVPVPboBqBWElvx_~zu}UTlfy7Mdf0FmPZBvAJ6c+1_#G9^ zbKw#$XaXn@9e{m0*cp zXR53mBoeVif*49IV(R?j|Fr;WYH5X*qOv?c1_pLM{1@ahJnPli`B3`jU30HiBPLuT zG-PYpFF`?RcX4XbEE$+HNeqiBiX%VuX`*bJM55EZD}8{oPkmpIO1T1GWt#>)FPXC; z+gD~_%FkBB*!GenQ)yti#ld9gMB9u*;8BztayioIE0dkmOgMo9L7)IOoQc0ElKr zYws7&BSuzMbC}s(x5k1AShNrg0ql5LWn~$BDQ9Qr=bneOk9ln=;ioSvV`XL;Ch#2^ z8lo2#&H`^BTi%mJ0&N2^08R7^u1w9$2$0_41WOeCtg;%W;3kdkJU#Vl1+Y!e%;b&_ zWOR^M=PvjhDbg!^_!@+cN4?;nC}d z>PUj3apD}!$-)}Z{MwD1o-rrMKT7y4l&4lQV$B^fBI&NgFglAac4ssz=)a&<2XnIn zt+vJb?4Y6k<2~HaVmr~p#^RDv3;$mveu9Zz9do$b^GLY199Z%%^BtTy9~y9k-LLqd z_FPdioj^j3T3D>R-fniPi7OH9eL_O#@s`~N$-S^->(&3Bq!=$ZyuZLt zNqlBE!_CaXGTr=^1;SxXK+|e&X<1LKpjM)>>DnB#W}h7jQhsa-!9GCApS!GMy%YTp zJVanHZiK;O|KGLk!k5&Z9_i(k6&TPFx>}!eNB9RxMEnGMV|bJsU-25cs>*HuHb^JwtL4~@(5ha{Xqh<>rjWdj~1c)R2sQj-6=e9I(|ihuP? z*3gh#IQt>gXIamwXDR6(>1nu+y8`en&*a;rYqum+^fUg$Qf2xhqWg8_eTC&(%B)Ue zN~n)kJHBN6YB8hN+rOPhlghL;1j`==t!Zh5v#PEynOvT0>Gb8~N{~?Cb+H)x54sEs zP1;L&-VrOz)f-b+@j;E&8c1YPPgIiu|GvoemNMdOvD4gTZONelsAOX$R%E^Fp$K@~ zj^L68XBbRP8fFR97=sAu!NCPM)W5U6jp_k5Giai|Kp_Qb1Sc04Kq(K8HioSR(|F)X zs;R5Pofon}ZNkvKb)UC^xrPSW9KMG53xn%A>gss$kF1{&pZAK~jON+gWu(hBVAGB? zQv&k%?_1qwS0=skSZ^78VZby$h9LNJX;x|(R<@$OX&ho?I7ne2s-9lH!RI(^|PwK$u9 z@@{f(Bf=_+s?JKe-hP+3sF~^G;e&5HiBO1^x+`VaaW{7YPyOA1Hzd z4DtRufL(u%i#RV-LU9MJXe?PyJ*Jac8fA=3!6d1n`riJF7dbt&lVenK=8oHCiD@tO~ zb_SQNOtC5CkF3I+)>^#ixBi0!X1&?E2@0QmF+>Rbz0Y7sM14q6=9B#Xy@Z#SSB+U` zVF4R5Y=)DaNiIm&koquLX{=mn)cPDe>@XIqyY+v>NzclGa(;g9!AkftG*}{m78v)n zwY9{Q6m@<5mvF*%XIvv$RmSFw#o;ctIlaww^lts(yYtk?hR4|N!Xh*V5`k3Ip5o!+ zP62QM4I%j7;6JdV_CCRlQB3DWg!;h8`T;9Sp-3rHr^fO@w(lv)N>4Nm7Z+a9&k|Ni zMHITIp-hRwc!-ffghlkjA_T<11g4-2LC*wG|GjYkTQ*n3W;mAEZZ(uqf_6X1tr?mt znI8x7G89Yov-bHQ`G->_3bo?@T3zcPH?`R8*|P zWNFXAR9b$=%-fnBg*WQ(@Q^UtymE3N9FL*z#}C`n>0rTp#Yg1iiqJcK^IqwV)&5>q zk8F`{9XsJ6+*zKTpP!$;%bUkYO%?Qg<1xAXmGyQMi4QOybNsxC_k1`|*+f+}3Euc! z1Vf^PS%>dgmE%$;_Grz(_wS4>EM}mO2H1hyG^v$%d}5-?_n%umxWwSck$pzI8o^TW z3Jh`pEWE0jc6?6u-2toUX{b}1$!ucN@1u*&@sjt|pCBwl-K0K5Jv$!=wbIfqbIwOZ zM7=lH|F!@Or+?2B(EXU=7M2sEoBZ>y`bI`dfJp%I2IM>QEk?jsSU?21n8W4y4>vjj z@9X=BK!?&WtEj3Pf4Ja(`)|?GhdonCMp_y*H8mBqEwsxuAt51{T2+**I8#k7R_S-0 zgxNmXh?$wuL`O#t5*L{8IXr*GIFUp{I(!}XlD#z%GWSiyrBM1uM{@-&L+@2ZfBiYE ztLsy5_gFJJdUJW1*tMT-YS*o2&i#opoBpq*FDS9SU54)S-ABVBvGRqcf2Mxnoy-Qz z?yi?NESOGw(uC)Q-!L29Zw_Cog0l@_y-J9S!x`lg{%gM z=9M6x1m+2 zAA|VyJ$wQj>Nmx~?j(>FQ*D9i59CSuG?xinuY@LsL;S*(QRMm<&)EOEZaL2Z{poxu z*xlhyA2ywxcX4*wDk>v3ErCZ)s>%k9f-3Nm2nYzEC+kKHkB;tMa*TtzUp^%m#tYSu zt>r+vZL0nO)FG{+{QV!PmZP0I2nPs{)Auua{hVdJlZlxBrX4+@;IPTT6zRqAw z5{Nr6Y;jwIx?urnV}d8+>IfthW+6CylltlakFn z+3PU%_*`xkd9)gJvyp*o8As0paUDx=%Q$zAyC2K;k<(4xV@T+ML&&x#@Dg$)iMg$D zltr$&nUgT;^vYGjU0-CXeT9~jX*zCc5d?beYMPqe4B0+Fp|e41%sqb?oHwUyikxqb zSP~Vog)`f)%TJQWpQuRIoalt=yh|UoI0X zjZCjdkB5*6!V%4?TU}s?ae9kfZ#&%ykBr~DRnbP33=9lK^Ys`T z`E*EdyySy{c6DvdX|?YWh}2=m`V%LV4xMlEQ~einzpesMBokdT4pABl^J3Z;&)kRO#B!_ zD_ke33DUz43iMv5f8e(MXAeuDuu*8|x51N^%+% zKt`AwLvBbORCY(DCkr9>~4=>fs=0Pmg zK=M;pn-2Snd^GQMaEm~j2@zHtFk+Bl-&ZQaiVp*cg8-T7*Zac z+nTVM5H5Fi_E@BQs1V2_<>l3ED$Bbj7@k*resk?70>q-cV>v7*aKST{GmriJsb5wp zXwr!c$fbZ0bV~^0I!7!pjyAlq?ebH%=B2oNtUZYTB#^r2<_xl+P7|^lm5pf3V9GWW zXoY5jj~k9eJn&_}fCIf}aMuzgKY!Dp%g4e(r^D6$TTdj&-O~P)p7AiYH(zD7Yxf}{ zcthAN3`@T+N5ojUes=duwJpinj}IL`*bLLmA7usNqwPbCichn{6BcOWVXND7q14iV z$Q3Z<b>f58UI3lmj>`%mH=+WCijms7(nJw|GoU(0VmH1*E6G zp8mVWCn930`)2dz&2;T+JcqUmdPGz!0Dv-uYD~?(jl#M*Qo!Yi<4b{dJb)7T8sM7c zbEB%OIoJFUY?j+SoKZX>Vk}M=8Bnpw!shLZ%F3{SLxA`jsIqp+_r^xw7^ta@*+do6 z1wC#Hu_JAmEgv^}gFZ1aF}NUL%!9E<4_#{pze`A0=)?CPK1|sdl);n>0X0Q~0Zt|c zasSo!7?hWkbnKm()l8=~4aa2tplkJZK+d)B2PMGTZW2qXfCWaw*&h-cW`7D=In%$t zJN_^-n;tB86LDHt_!;}25WtWRc_8~^FWH^u-%gs;=^a2_NKPJu5V;p`wfS#II8<#{#F>+Ecof8!(P{heiZO;97>zqv74Z`E$m5a*qw8OII zVC|zK*6w7iH|j(BHk9RbN;Igts{z)i003J7Sp<3hvHurv5;1DMnxt(6hElp-VFf3& zlsR;N8A==#wb-t#lH~OXjR}mSX$(wECKi@1Ywl&&7ceP#Pr(9$NRafwo_h}kbI|lZ z98ZnAp<~KDKcfbP#OkVfA@5gsc5q+NQy>UoyPMVNCCwnc6BRvR&1|1tbRKy6<>qn+ z!KNU7iS}(GNI@veWFS%Mw5em>J)8NCuJ`#B5^Uw2{p&l#ytX0e)gbLERRu5 zPwzV@=|X3B=|Np&)avE*`zsP6i3S>cg!$R6#Zc8wh$7bX^V!a1Y(xYGOwEu>QaoV; za8$(~OGh?Y5-lVYu~#7bLgXh8t^-NZN>LKx?0RKyoS@ArCuJBuP>)z`o4fk>H_o!kjAkJ>I4%&BxvdB zIc>%nySwlga)BIy@fTuLKf{O;_9_!P?3vovKj6wNxbPq@DMYGYbOf~$0(1gFU*d7le$20Nu@UaiMOvldF){Y1zY+cA98fLaZ@Y}D_N$f*oqJ=* z4c<;@me(620&k!bkt$Ssgof+^eY^*ppdf)2f#vq*XKS-bR|xOFP;2fqOy&@Vf$HV0 z0GzW@sCA_i@~|PN+WkeK@3o(&VK$}(gvugiU?R5)R&GM8kwfUPp}sx~;MGB?F`SeS zAM^e(EtR9mYd?6e&81<=R~7{}vbyw~MtV2~La z7=UO(^v=fOJkQNXSPQhN?-eyYWt9lZC@oqC=9 z9RyYrAx|G|hfR;2s{fqw$Oj8FLYvq=|V)2IMS<-xQA**(}#gnz)` zDhYEkM4#Fa`UH*qt-5*msnbsL%^%0eZ9*KSZpe9c?9J|u#O;mz4_=YT`R{udz-l`i z8XAVifF8r)+qM&gyIsfr056}|>4ncBC>>W>DjLOy`upP_laj8|y-e-{nxx7H%8@6a z8qT`9se+K)=Lv|wArO>I4)e{L;CX1c0;;ip(f_vff8Wi62M?U(juHu9EL zhAag)G5~9@WiB17rb{wmO`4RGh53aPC69;R>Q)>JC+<7 z-R?@_Vs?dG!plMswxH{9m{G8d2oGQSR9ZpJ#Dose1biR8!piJeglfs>d>=d7?g3o2 zVqaIb4R0%*PRkGtPHDsq#<2hPM$T`CQ3{wMA|e=>nez$?f?x-OzXWJau=>MxP!t!x zn_}ek`rF_mibCL2vhj`N@pr35HBlx^$W$TM8~E zR%s?C5t})(UdW;o%i4gpdiw=gl?twu?Mh|mSUaBu%dg)eN$zY!k~rtHRb*P4WL8U^ z!3wFI!GMe%oVDKyQIEU;QFEccw5=`c!NCE>pp<Opd=XfarslzJL$(?B_r#>8(Vbnmzv$iW?68!Vl z!${RlKzze@m2FfsW9&cbj@cupriXQkv%64Z?;Nx83C!fxp&0{y(=|=YU~^@eP8I z@KmMI#9a?yHH=M7$x`C{hLg}7>O2$>Ui&!@)p9hwPC&62Y#)7rls16qx1I=}LG_HF zMB6=Oe0M8xcMKnTz}!izY{f61iavdcsjk+;!1&%b_;l@f%ULO-kB);QRkKv9PCrj1 zDlLr^F{J~T4xk%DM^3DI(IJqkp%iI@0VsS+M_M!}_xk+M@8W7%x!Yj)_bzT)E;6J$ zStM~<_P-RYcceOv;)aW`Kb2KLC_`>;S;p`7_J9?Jq`f4mcbn-BUpY(}J%_KOMQ@ru zEmyPB^mOC64@7HJ+)~_z+qxxsm)P2_Ru&EIz5wv(`ed>O#KxdmXE5?uLV;JqqFrIj z!NvK-B`AN#M9*ugoP1~{^|_PjH~H)Ru7@=Mk5Lw|MUxBEOI2t!`e})a2jm%rcx&A# zf89Gn0BB+O(;rbNZqT6r0P(~sh{f&P|J=%f`CuNO$f5g{_1{5sCSP*(vYiaOB3` zTVUoDizSynzrLpWrtF62eM_$K36idJV(r=_5{Fw$m!wZDcL-sr(M7-3ia@Ls0Gr&~m2k z4Fc6@*-h*E!U0V0eG-*M9jKHo2?}+7*I@U{DkEzF&;cS1XIL%AYSrzYZ!gqpXvlD# zrVSnV1S}!);q#;-6K`Q$Z|Qm^Q9B5_+-nqzW7C1#kyxc9@yF}cho~s?Qe>pbkJ-huZISOV zE%T#YIECsxH6O_(=+xViz`VHu4L?BIpl;B2ZOUq~vp&)!d2)|fmaMngs9{csOx***kD!hHE#xO~%?z}^=w z@sS&b*^$DJAEhPF^}ApRA%(>#(coAMX}4BazhhDlaoKBiM`)|^q+FVoLQ(~9uY}0> z59wOH3aiZf1OH4Pal{IpGAwwkJc=RL?|$qcI9Qkxf($5BVwelX^L>HP+j{KQg&Z`P zxuuHmKF{uM{?S@J#^2^`Fz|lK5~e{e7|{0S#e-5loUllHUTNk^>YdzPCnG2RD)&K$ zQ_s(zlJDJ~lNma*;)P)Ky86Anq(29-7XAsnfk}HI)|Y3Jsxa=bjOW1Jv}-2Vm`4`^ zC>bozuHoJWTmpg#dJ}HeD7TjD0JleVdWd-CX~=(tV`c+t&$lgC=@H%PnwmSvn{EHE z1z-;&Mz1A(tE{M4*x1-Ozj8Z_5%zPdpo)Vuk}jjbT$4gCvO7S&aQSS}MegO}|GGv) z%gRi>PDmkbbBEuF8qTb*+8Wtld%F42p57G@=j#8q{cYEQY`BL z@k4ya)pQp+E(xRtl~7;Ds$wO5&L{ zc}j>0md^6^p-`|ui{9bny8r(Diikc=2N@NmoSfV7Wt;1EV#s`!tj4%S!N=3DOPfFX z;@uOH-ja^wPd=oj$>(EY(pFK;Wq4Z7aD5rQ@k>9Oju`6|Z+6Q$so2+IHT9EjHs*n$ zZVJg!?_V?p;$sc=)fc{g2JP9RvrI@ONdcoG^(@Q?OGxM4 zcRkK(8xr3&&8O9bAy_11<}n-Jzk#FMmd@wxuZIA?m=Rj{$K0rCMUWFlz9*Ux z{ZF;lidiSt$rEvOc$l^u1CC2zAsaleZeJrIZH}7J%EW4MdoP-*=Ksu87wIfjRv&}l z$*x4T3(J~l3ZW1dvy`W^eNiNsB^AO}$O0!+CKvv@zMhWyCrzjMC$jZ~1L?Hv3152j zZ5gP{AM)kOp~qof$hPBe+OgN>if)Nod6BI9H7sI1F<`|1=(2=cuZB?&C$1%%hKkET zHDsF6U9}>#KsP;8HaOF;_i!y^Q%5E_G3X`P;Scj3{ueJ^BoF`l*E(<{TxmNN>EhqU zI-8x!)Hq(7h$No+L2CQxALZ|(B`)GesY=nYl3&-H;#1@0x}U365igwyhZHoTC5bc> zfp}!3S+H-_$ggsk1I0{+UC}ra`Mv9-X2Ny}=xENJHB5#9xl6<#z^3%#lL7 zka82L@Ja4v4@g;Ba(gha>{`~49FcB_SyxLm**`@SIx6_}oSQuK%|-dX!pzbks_194 z8`gLKeHUJDe67>w4{(;Lqjgxd_uAB_-0p z@d2u>qN5WAE!mWv+g!6F)#2I&usF;fuRHjv?-4V}M?&RrK!#Pm&c5m{oL+c4)y~ARb$_Z`#$tf7b#VG1urVxyucUnZkW7rt@!^$VKoXJ}Ol-TlUg zW@6-S$d93+9+((#v;JLdWEZ)wFnzUeSOF?h zo{=H(2SJq7bFv=52P!s&Wof7`Ue~;kjYVOCJEhpAl$Bk1`iBU+Y+Ao01a+Cf%MvZo zP>U8Jj0`3bUyFuB4@A7Rjg zCng)Y-RiJv8N@#$AfBTbPtg$9&58ObhjRB0E7nw$)5b^n`jgMkl%-Z~iqR0l{Q=a3Sw4sTwT8`;#{NQfuc>jNeS;YqoKRtSHCZvb7L;Jq zWW>)aFh`l0!9okAiIewzmY$!AmY^>6DgEr^gbE+S1iDNp^l0uJ zFWs@TV5<$zo%heW6j7#@eAZ*QwY8N?a^F$zx5*eUjaf1}Y6=nm-OE7djYmj940*ZGP@C&8c-5%()qt52$$S;#w5u!0C5O5ryoGgJTF;d;Y zTpUOb1VeCVG&nqC(t{2MBN)hfbNt}2?lKM>nD^JZ&;vvzx?W&mhu~m&z2cTeclSR1 zBL?{sh&zDR*DXQUMFyOU2F|WqOUVIhIB`*+)+JGoNlmd9aJT&3gp5kBv<4Ld*nH^YaY?N$z#cvQdG$}22Hfw7$F0qG3PLf^Tx6P6%7 zGRF_5e!yqdXWrE-6-fYjhS;&6b;?RVX7-s^7jWUjvW{z=tMcQH>=xIY;0)`2sj5qo zRKrJ%<#9S~bpQw2Za*@#y1Nm$uFa9sFDd4eFpE?%!YpRhkfktJ@_D#o$;635w?Q!R4bI)M%P*;pf9Lpt)B;5K`1JH+(shIsEF%CT5A+PP!*G5wSD&+aEU}m;{^F{)eHK+`LFT7K(1vJqq4;o%;RH z?gumyDs@#=sZRMK%NHE$tVfw3dujWGtiefhpy|5+Qi?G@W#$Yv%I!`sK?>lsR)9Wg zgjx5!Wq1X$`PWJfW~%r7Ba@T8#Y+NsK(eOCy?*q6XAoPmEUoE}Ie5}g+8C4M!K}P= zb#bHvtPG;Dfm*;?;lLz0lBlD%g__G6P|6=i0xtc0jk zMk-N~ipuz1pYN}iKYG2CbDYoneUIzDuInD&xNkw)y*q!%iI}jds)kQbPv^6kioW+y z+b?jW)iSaDzU-}>93kDNQzfIVQ*PPt0HD#Z17)|nr$^)RWrf*u`!Y@N*6rb*26BvP z$tZ4xd)3z)y?IrM4F0lhpK9jBr6c|B9@VM0-=ZhOoFi1uyz99)tw+gN%z>>Rr(@q? za&X@7PKQHF)B5YCDNOQHDo=>ABY9ysnDF06&%Kprdbw3IO%VDziaTr%;}d&j^b^tr zKyIem+GhgYc`E@dwT_RIb1l6z{!Q{o1=P;RQx_wGp=9{vRs^nU@Rgzf8g zw)y0&x|r5|J%)1*g8CBhxj`pBR9}oglX`p;PJ2T~QS35St;kwz5jkdaV^3K{J%~)7 z&w-5xLI8<|y3r=f+^YnHLCLLsc$ezPI-?|Q&GNCJ{rag&c$f3`X~voc8`v^}1Ke2VDBPyQwrt29C-29mK@M zoRU5hsRV%LKob{J$VmI>r6=b@EhJmP2Z*e!lxslS{%L+*>*`e%IyyR>4ky}N!DG)u zx-Eoh|A?j5QoLzkc* zA7)r8r{#HYkD}-WeQy1#>zy_HL%R5;PU*|>aSIJ;7d#JD?{Adq<*Qy^tuD%4nfuNS z@Ks>{gw&n<=ywYX3;7oxk2MC|`kK@`+locuOgX0E85w+?Yt>`(9XLSp3jdDRR0>GK z8LqlI@zR3lUZLb(vlA!uN@!i~XS3ZYe=4DVbdamyh2w~nLTYyXR}v0>HIMm%bPl)D0PJv|1@%*>(05HYFq21k$Y7r#nu%Um2+U>+1#`_#lWM)y>H$@VnQdK$_J{;;jMySFIJ9+zPvIfI2 zRJ134AkO%V&ACcT!uTFiHda)fQ^2wrhb7`l$V6pXiBlm|c+pjpUzLJz)^ic%yDHj9uXd!tQ`V2a_janrn6H6nwOr zSF>*^Eapaj=1Ix$%q`Squ_J?dyj}IO81Ll*M?uw zbm|r6g)>n*b$5Fy8BWew_oYv8ut z!vQ7%$j?RLiTM9=(%12?Dp1?=@HAuoiFF6E>HQT}rDR^-KqIjr$lzgi?C(^WGQxaV zv3RmhnS{sylTK63&c?<@#@#&_uq&sth=_=Ecat1XYlmg3gr>G=v&_ zx-+7nzK8z$<@IfxPqOiFAasAejv{n)^vw#qOTTMP#Fs@)^+me}NSb{gwOU2&+>Gt} zoWuHOLf*_%UyYz+JFHDg+&;c*iBfcqPfb&3uP2?Vkt-*=eE7MP_Mc<_ac8J>oU_Fe zA*LAJ1kaV#xXo2I-5JX#K5B%Q=Btc97R|FB*#6LBM>=re0D8$PmoXsYOT>!ZIvQ}- zFwdq(X@BR=oqV7BD(`%@;~Ies9gN6^;V^lgmp6v4w6xU8)%Cxn>sXPJR<{5NJhn3B zWM@;gwY4RdCF4@OaXq5Hx3P>Rc<|%VPPx5%nQE;E?pD8F{*5AqIk`6kofn$hPd{JE zlK)VW4+|w2e4CCsGC8ET2yc-^?aP-(uKrt67LZt@cy#7DRsUpxYHp2X$aJp5>M1L` zNBgp4EZNl=?4_GORIvXF)$qSr?6*Hq?MgxN*VHhzt8W5j4s9s3#xvwwZ+W?&TGd)W zvxOwKC!u>Fr;Fm1MK4pe;JC)x-C2H`PCoO|zi0#@BV4?yB|7LxP0d2BdsM93KyV?OM-5<%ZkjxVf>e5bJzYoO8U!-SPR2 ze`u?TM8t_-hNd0PI^(yk&{<%Y41PlAx>e^M_bU>4IWZeTqdt_#L_1C= z(i$&oX(trOV9Cx+axD6l&6d`YoW40)E$Q^(jz;zhh0G*8xgzqKs~#wO2N-)~FoL;#%B@e8ErAgm=RTX`)qHc<5G0 z$ZzlOJ@k_+^mdPp18z8w4+ia|PT0vKLjAr{ri<-`!ESkZdAWmfzNu=w)cUR5$!!|P z|CRe5DYN5&b}sYXOXWK5M?BB0{PrP5bwvBR7M%=Z+j~TI<89ob4b`8Qg}3tX^0orv zp7N?kbj3s>Fify8YAF6<3np5;jeJ})hmC)v2b&kSzke@^68Rgj{9T@@C|iBMCuFtr ze_Zmmgj5g(4$jR1uzsnAqOGJt{DyLMM#ASUNi-VO2lKa9T1KPSN&9f({CNrRvE3HN z<$(IBPTfFff=Vdo!2=HU#IqIP`9Vd@3xO1r?Yb0_`h^R-rEMA*a0$^$W9FnGmeAt7 z2gdcG+8l$w-Y;M4?oAe2eCtFKV4!hd`k|xxRv_^G?fG53cQo$o2{J4V>~IP7_2J7g zWdPUP?%{ZfN4?OKJXRhaxhz;LbKs2eS$7A)v+4bG_(D*z7!~0@?f$5`nk&oayFu$RHqvGWGtxqj z3Qf!eNOX!*7Ic$$J!uB1 z(Rh@PO61K9TnSV?KatQ@;84#*gK}bxMq$wbWSu_P*8$dD1u;zy}k@#3|c|X9o_Un=9sgYpaTf-nmBt|Q~bS% z%#lzK+9|&-Pt`ev9LQj#j@qUb%Jx*^pj0c>Dz$Qr3v1som($GGC{?ro$)a;2NxX_n z!CD%wVlHd#C(|z;csD6R*C|c9*als$Nm(*n%a0Um zCG^hPn1wlLXi!&KU9`UREIKRcSJ4_rf0^T#H>r-ch`c+J3~NU(3y(VGP$GCY4xYP z=VCpTyQ}nrlBAk%Lp)NOv(Bn~uF-zp)KAz|KJ4#aXkw!A3D$P;&zbs??@KkPsBofo zH*{a?D|2)lOd;QJHgmJHDY5PP1MB)+Ab)0NW)ca`rd$s<4@QuEHJLeMyb`z%ZGM+w2%b^+2O#6% zq0Rk{hF9wX2&Owe1+1NnSRSRPqr2P39M%>vJQw`ZrSLW_q6p5!lp7geFs19jwC0>= zSFolK`b#hz2{$WfZJ0H4NVw7j%C+dbvac`eP}WkT5k_!82E$|2 z*_ml(X2zX!1yuqh4PX|xo|f0hF`YzThrEB;Dq!P^nth};bOq0zk+`zE=qyDM4#Nuz z#qeVVX*4K&td78U@vd&(ytz6n+hcJB$d`Amnmvi%?t=_u0mG|pf*by*1Y$Z3r08mLorpQ;f`XF4hz~Jz;KPnp@J%$QRr#GZ_+ZYIA^bE ze9{q?t#3RwWNn<+=`|VCDlw@}4Gxhxm?fxEXa|!ALfaRh6UA+|z5|k_dtuRWal|sM z=*AU=DTs7P3^a*lOVGqsfOPhmdK+C3p-V$M9uNC$RK>Usx#+e~WWpy1bPPZ`5~a`2 zK2$5aW}IUxTlZ7}F`DY=(W9o~oU7mg3MCmLi8Y2An_W}x>k9{X;hdcmz&i@r>kYMypl zS?rfmqYYaiC3|@8?0wC_V5CSp4CE5i+s-~bUm}B^8hHA%k&$481;C8v3bQc5rN&I` zOd6QDFcQV0J8)>uU!E|)x4{t$eBrBZs8FyKY;&}KuxQmUFz4jrGTS#jYWHH1Qb}Yw zV*O_?6>X4)^N(dB3WLg#*VvdTXUxMtl3);{w5ojap881AHIVwncgVBjj7|Hv6k9Oi z%7Q#cCgk3@h|<@4?Vx zQnG4l2F5Rx$jo>rN5=JtV?cDF$OpEDl3~!(RAoMQs5JfBi?*o(MtaOFEIIY{exIhD`Cm}5)TAsMBpx9Ve80*SSEpjr@5Cj~&oME$xaQx)z(u|XnQ?^9u;R16- zB_)jl^C`@n4AkzvnDay_4#BX+;2%7PdP^!OaaajFS#gH4*_`i=as?nBfrGBCXOw*r7u;N1^;7XQ_WfEO>08+INm z8rBewf5yE%$&fa0C>+Z)AbFdH#x%fMn&`+-$%zYH7K6^4ULsf4!?S~MIAWGCRbdC+n`5>A*&=^1?CqzG6ux>d+^|aogy#9U*z&D zyA%_(Q%30s>hsf5Tnj)14*Al0!t8fPKiAAuVnKxBiBO20fW$$*hAgO#I6V8nxF{ZM zM5|NICMK+Kr_n0lefZ#k>CvNFv%k2QbTWiKe)s?hGOu}YB5!-Ksrc>N-yub{lzPGS z@pn0G_pyWjjwV@xOgIUY8P6Tig!lV+y=nQA7y;caFYki?%2fmudpEaRW~PA_%T3%V z)pD>KU_+)Bzi5NwgHZL9K2}>8zy`J)9*%fnOrn8hamNZ|^@@IJy|bF)oMKXTa%Zk1 zvfMpp20uk8Tg*Anz1o9Mb(A$tQorr=bJo9EThjXrV;btsiJXjQCY`+7{#}@E9uizL z80n_Rj)k*IYne!Wv}&%fq`&x$e9Y;lggR_A$n@Kj1CB(#+;+Zx~!_>{&xH0y!zstniyidD7R%pPvxe{9Ivl^ zCZoaTlIEMy;$l$OM^DQWxc$iS%xL4ZvH&AJJRKN-Sn-~y#5!Bl@>(biF)iFmNn-|L z@@a0a_TG)ZWi1Ysl!P90^8{P0{zWZsu-*vj7b~BtKRA_bAD91qDEH#wb9Gb}a7I1P z5TY5ZnNzdprJbzkkFcND4^$7|njtW9WQh^ypV1@C2eYy`h7)N{+Q;hTYN*dmB3R^k z)!qD?+qeLIcvWoe%g7sFYs1XlQyGyMp(yr8$qF(l>K3G#r69pIDoFW^(j5{Q@Ur?4 z+5*l=8{~=5M%_ui`D|#&Okb44`P|T)CnCVe{pHggcRk+-gE|8=+Uh6=Y8OkX(5{4y zluwY~*ux&c>EgwX+q({Dk2({Vi}16-sYBv*Zzz087f3NL>;oO!(ajC0#WmPc-2!ga z-`@f1myZG+buOJlwH5SA29mouBecm1dr|2idcHc)os*4zzwab4O1(B5%uJ*ezisdGV4F{ zZU^)OMn*<<5Z0EOv{=Z^v*hD#F@*>ZjKx8*6&_{4VK5CzS(?APl=+l#?HgAD_ZeYC zpFA-!QKNjU*dood^`1?6S9do95OG2ql(oKaF6EHlK@hiC?#TpMY!H*~S?Aj$8;e^Z ztQdOzdRx4{X9w2N$sZ|0+_d?(NrcSY+2{uya!N{y{yk@35uyeMDr8Wsdm{4W zC5pOdQtYmJ^bVd^u9&4pTdEkAk12TM>94MDlo-x}YXZ~S;n0Ujow_ShCuQ%M7vq@B zFb62s%;|!YQR%(p@agBDM4FwhGziJ?;hMfDwmA^IvsE2cZFLZmM09jCR<2rAm~@Jt zeR!=?%`aa6w60F8MQ2LSX?eWNg;w#>`}d75ys!mG1OUZc;Ej(6(LYJlHk}B>52{K2 zkaT0eKvi`$F}nicV}unA9$;Pxu1@W0<_C{tkH+`REQw|+{1+duk)UC`12rXvX$02NBlSP2MS0uTAKXTI| zGoUlT$n9(0y!8LiVa+w2r`$X#tUOzBNLPKH)P%irQq(NA(3IkC1BcPaCqqu*!}4#A zuaq8Z$+)hB+mk%${kkw{_}Z{+g0zY+=l=}uS;CA)>HM5n8J|jU0FfY6ntrqFvPA1$ zoEzU_hhdL}`e9|oj7JMuTIe)C(}|v3rqXw z?_X+d`eu095WOAIHVn_L*%VwV-!Va=Xa+fUNWeo#`(W%eGe7}F6i;i%7@K%cy zYYDu&UV)DPW`15j$L9^O;4I(oYL8h%f;>!>`;zDTE7a!RYfD{C)kgisqMa<~D3!=X z2#yxic7*oLI5^~-DDtaXDYd=hE{|$zghWJwn7+47$(B09S}5Uo<;{b(nh$a< zBz2%~@LCwxs7!QRx_HLfRanl|a%+UPFpjl<+myelxV9`g-+4PC6q%2&9dHYH5V*|e zQ}=i%3nur*yk>8AkUQ3tQWgvy_Tgw9_YtS3lFbm0;d460hOz7M8Jf6^;lZr=cg}9EQpi1h*{WQkZ{=I%1 z`%9@Ym;rbO6if7dEEmGHhsSL>4Y%!^%QZqQ`NhSIAS8gUtd07F;6cO4OaNoe>x}|H zZh+o_>V=Vx`uwuQRP>Fn8GQ*V_FcucgR9{I{x^QAhKF1 ztHRCkn;^|kRHm=Gy0!6uu&E9B7`z<=^mHR*V?l!-A-W}0SopXdnnN{(Dqb$AKCK6_ zb1&zG3m1wv7IDu|-2*s-D0F_?RaHK?MIZwumK_IV{^iy25-w~YsN&BD&V+p6U3b3K^J?jQ< zcJ(UuPk%>--4D!!D%{d$pxFXIpn#EgI}LS0PcZI`)g&e*=L2qF;HR|V?cu@k<;#~E z+5$SL_E|D5FgB)vL(*^05I< z_b>0dIj`b=aj8*`SY-IwUKGlcZ?F!^g$Xrp5?=)9jvnVLgEVuR@dlI}{)`kK9r209 zOJTTx+0T!a6%kIR92Du2pCRHkn|lXcxM|i6^lYz~w+B+7xfK_IoKEFs%^39)6}sCD zq8H&rApmCsU2)FH1er6HmKfc20VIMI0@3JC1JC{R>61SeD&lW)va(dQ)+VnH=o9`5 z%2xd-@*vQNtWO5*)(2z3#MU)qpOw|OI~gKSN+Ol3myF8)3c9tAW-j*)Fzu9#jC{`a zzkmNi|7r&RqcM80C!E;U{`{QhiSozEzSTR6i-6)^qW9fI`{S^5I*uTi?&MWhCsl?Q zSxBCz+d@USTOhumJcZT}P6KcjD*G$|dNVp-9Okl`sn23%{I0y+is)M7&8XCKOq*fT zKQJ)tT#XZiuH{7OeGIS(z`}EHd8*F`V{0|ypCj+065jt+HLR@#4kLr(<#4zGiDyP^ z$c7PAA|xyHZC4anYgyeA4&7wINjE)t@>>57JC%#CJdMjPZ$A;Y$wm%YzHm*)){P2( N40KGi%QWo*{|^~kJ8J*{ diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index eeac9534c01e..b95dd9e9d3ec 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -332,22 +332,30 @@ Paint _getDefinitionPaint( } /// Parses a @stroke attribute into a [Paint]. -Paint parseStroke( - XmlElement el, Rect bounds, DrawableDefinitionServer definitions) { +Paint parseStroke(XmlElement el, Rect bounds, + DrawableDefinitionServer definitions, Color defaultStrokeIfNotSpecified) { final String rawStroke = getAttribute(el, 'stroke'); + final String rawOpacity = getAttribute(el, 'stroke-opacity'); + + final double opacity = + rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); + if (rawStroke == '') { - return null; + if (defaultStrokeIfNotSpecified == null) { + return null; + } + return new Paint() + ..style = PaintingStyle.stroke + ..color = defaultStrokeIfNotSpecified.withOpacity(opacity); } else if (rawStroke == 'none') { return DrawableStyle.emptyPaint; } if (rawStroke.startsWith('url')) { - return _getDefinitionPaint(rawStroke, definitions, bounds); + return _getDefinitionPaint(rawStroke, definitions, bounds, + opacity: opacity); } - final String rawOpacity = getAttribute(el, 'stroke-opacity'); - final double opacity = - rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); final Paint paint = new Paint() ..color = parseColor(rawStroke).withOpacity(opacity) ..style = PaintingStyle.stroke; diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 8653d1bbc123..1dd8ef33286a 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -28,11 +28,19 @@ class DrawableSvgShape extends DrawableShape { ? null : parentStyle.fill.color; + final Color defaultStroke = + identical(parentStyle.stroke, DrawableStyle.emptyPaint) + ? null + : parentStyle?.stroke?.color; + + // print(defaultStroke); + final Path path = pathFactory(el); return new DrawableSvgShape( applyTransformIfNeeded(path, el), parseStyle(el, definitions, path.getBounds(), parentStyle, - defaultFillIfNotSpecified: defaultFill), + defaultFillIfNotSpecified: defaultFill, + defaultStrokeIfNotSpecified: defaultStroke), ); } } @@ -206,14 +214,16 @@ Drawable parseSvgGroup(XmlElement el, DrawableDefinitionServer definitions, /// Remember that @style attribute takes precedence. DrawableStyle parseStyle(XmlElement el, DrawableDefinitionServer definitions, Rect bounds, DrawableStyle parentStyle, - {bool needsTransform = false, Color defaultFillIfNotSpecified}) { + {bool needsTransform = false, + Color defaultFillIfNotSpecified, + Color defaultStrokeIfNotSpecified}) { final Matrix4 transform = needsTransform ? parseTransform(getAttribute(el, 'transform')) : null; return DrawableStyle.mergeAndBlend( parentStyle, transform: transform?.storage, - stroke: parseStroke(el, bounds, definitions), + stroke: parseStroke(el, bounds, definitions, defaultStrokeIfNotSpecified), dashArray: parseDashArray(el), dashOffset: parseDashOffset(el), fill: parseFill(el, bounds, definitions, defaultFillIfNotSpecified), diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 193e065f89ae..477d359a90f1 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -481,12 +481,14 @@ class DrawableShape implements Drawable { final Function innerDraw = () { if (style.fill != null && !identical(style.fill, DrawableStyle.emptyPaint)) { + assert(style.fill.style == PaintingStyle.fill); style.fill.colorFilter = colorFilter; canvas.drawPath(path, style.fill); } if (style.stroke != null && !identical(style.stroke, DrawableStyle.emptyPaint)) { + assert(style.stroke.style == PaintingStyle.stroke); style.stroke.colorFilter = colorFilter; if (style.dashArray != null && !identical(style.dashArray, DrawableStyle.emptyDashArray)) { From 257815f9ed0b94be31df5337e3b442ac7db13d07 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 31 Jul 2018 15:53:21 -0400 Subject: [PATCH 130/512] update changelog/pubspec --- third_party/CHANGELOG.md | 4 ++++ third_party/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 02ee7e8724a8..ff5070fb1afc 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 0.5.2 + +- Fix bug(s) in processing stroke and fill opacity when stroke/fill are inherited. + ## 0.5.1 - Consume latest change from path_drawing (fixes exponent validation) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 1ceb90ea37f8..1b8defc80b1c 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.5.1 +version: 0.5.2 dependencies: path_drawing: ^0.2.4 From 6407d0d83cbdb7d758b51a377e8d20d9ccc251c3 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 31 Jul 2018 15:53:49 -0400 Subject: [PATCH 131/512] reformat --- third_party/lib/src/picture_provider.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 03fff791f740..29f987f2c989 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -475,9 +475,9 @@ class NetworkPicture extends PictureProvider { final Uri uri = Uri.base.resolve(url); final HttpClientRequest request = await _httpClient.getUrl(uri); if (headers != null) { - headers.forEach((String key, String value) { - request.headers.add(key, value); - }); + headers.forEach((String key, String value) { + request.headers.add(key, value); + }); } final HttpClientResponse response = await request.close(); From 89ad74cf0dcdc1aa14597641d8224ea6fd0cd732 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 31 Jul 2018 16:01:10 -0400 Subject: [PATCH 132/512] fix issue for master :( --- third_party/lib/src/picture_provider.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 29f987f2c989..dbcb44ec2e81 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -481,7 +481,7 @@ class NetworkPicture extends PictureProvider { } final HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.ok) { + if (response.statusCode != HttpStatus.OK) { throw new HttpException('Could not get network asset', uri: uri); } final Uint8List bytes = await consolidateHttpClientResponseBytes(response); From 27747231a14b9b6896fb11b3212044b66fffa6fc Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 31 Jul 2018 16:02:07 -0400 Subject: [PATCH 133/512] update package --- third_party/CHANGELOG.md | 5 +++++ third_party/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index ff5070fb1afc..91188dac9846 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,8 +1,13 @@ # CHANGES +## 0.5.3 + +- Revert `HttpStatus.OK` change - not ready yet for Flutter beta channel + ## 0.5.2 - Fix bug(s) in processing stroke and fill opacity when stroke/fill are inherited. +- Fix HTTP network headers for network pictures ## 0.5.1 diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 1b8defc80b1c..ad3d6858b26a 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.5.2 +version: 0.5.3 dependencies: path_drawing: ^0.2.4 From a95d65510460cf1a534d3695ae268b80ddae3fc0 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 1 Aug 2018 22:22:55 -0400 Subject: [PATCH 134/512] Consume latest path_drawing package to fix parsing issue --- third_party/example/main.dart | 2 ++ third_party/pubspec.lock | 9 ++++++++- third_party/pubspec.yaml | 4 ++-- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 094db2571c89..5c724f342028 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -83,6 +83,8 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; + _painters.add(new SvgPicture.string('')); + for (String assetName in assetNames) { _painters.add( new SvgPicture.asset(assetName), diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index c604d39a5299..d6dbe787d5aa 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -220,7 +220,14 @@ packages: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.2.4" + version: "0.3.0" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" petitparser: dependency: transitive description: diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index ad3d6858b26a..3c8a7dd99d84 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,10 +2,10 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.5.3 +version: 0.5.4 dependencies: - path_drawing: ^0.2.4 + path_drawing: ^0.3.0 xml: ^3.0.0 vector_math: ^2.0.4 meta: ^1.1.2 From 8ed7a6fe477d6df8165ba76561ad92c768eb1c19 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 1 Aug 2018 22:23:46 -0400 Subject: [PATCH 135/512] update changelog --- third_party/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 91188dac9846..69246dee9f7d 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 0.5.4 + +- Consume latest path_drawing (and path_parsing) packages to fix issue(s) with smooth curve handling. + ## 0.5.3 - Revert `HttpStatus.OK` change - not ready yet for Flutter beta channel From cd3291934f8688d7fbd851b66c58b62905e0e3a5 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Fri, 3 Aug 2018 20:13:10 -0400 Subject: [PATCH 136/512] Run "flutter format" and "analyze" and clean up deprecated warning --- third_party/example/main.dart | 3 ++- third_party/lib/src/avd/xml_parsers.dart | 20 ++++++++++---------- third_party/lib/src/picture_provider.dart | 2 +- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/third_party/example/main.dart b/third_party/example/main.dart index 5c724f342028..e2bccf44cd19 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -83,7 +83,8 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; - _painters.add(new SvgPicture.string('')); + _painters.add(new SvgPicture.string( + '')); for (String assetName in assetNames) { _painters.add( diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index 1e17f9b059b7..0386e526bd3e 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -24,8 +24,8 @@ Rect parseViewBox(XmlElement el) { } Matrix4 parseTransform(XmlElement el) { - final double rotation = double.parse( - getAttribute(el, 'rotation', def: '0', namespace: androidNS)); + final double rotation = double + .parse(getAttribute(el, 'rotation', def: '0', namespace: androidNS)); final double pivotX = double.parse(getAttribute(el, 'pivotX', def: '0', namespace: androidNS)); final double pivotY = @@ -34,10 +34,10 @@ Matrix4 parseTransform(XmlElement el) { double.parse(getAttribute(el, 'scaleX', def: '1', namespace: androidNS)); final double scaleY = double.parse(getAttribute(el, 'scaleY', def: '1', namespace: androidNS)); - final double translateX = double.parse( - getAttribute(el, 'translateX', def: '0', namespace: androidNS)); - final double translateY = double.parse( - getAttribute(el, 'translateY', def: '0', namespace: androidNS)); + final double translateX = double + .parse(getAttribute(el, 'translateX', def: '0', namespace: androidNS)); + final double translateY = double + .parse(getAttribute(el, 'translateY', def: '0', namespace: androidNS)); return new Matrix4.identity() ..translate(pivotX, pivotY) @@ -54,10 +54,10 @@ Paint parseStroke(XmlElement el, Rect bounds) { } return new Paint() ..style = PaintingStyle.stroke - ..color = parseColor(rawStroke).withOpacity(double.parse( - getAttribute(el, 'strokeAlpha', def: '1', namespace: androidNS))) - ..strokeWidth = double.parse( - getAttribute(el, 'strokeWidth', def: '0', namespace: androidNS)) + ..color = parseColor(rawStroke).withOpacity(double + .parse(getAttribute(el, 'strokeAlpha', def: '1', namespace: androidNS))) + ..strokeWidth = double + .parse(getAttribute(el, 'strokeWidth', def: '0', namespace: androidNS)) ..strokeCap = parseStrokeCap(el) ..strokeJoin = parseStrokeJoin(el) ..strokeMiterLimit = parseMiterLimit(el); diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index dbcb44ec2e81..29f987f2c989 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -481,7 +481,7 @@ class NetworkPicture extends PictureProvider { } final HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.OK) { + if (response.statusCode != HttpStatus.ok) { throw new HttpException('Could not get network asset', uri: uri); } final Uint8List bytes = await consolidateHttpClientResponseBytes(response); From 0b543568172278e68f8e900dbe6e45aaa24ff0f7 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Fri, 3 Aug 2018 20:23:33 -0400 Subject: [PATCH 137/512] Revert HttpStatus.ok change --- third_party/lib/src/picture_provider.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 29f987f2c989..dbcb44ec2e81 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -481,7 +481,7 @@ class NetworkPicture extends PictureProvider { } final HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.ok) { + if (response.statusCode != HttpStatus.OK) { throw new HttpException('Could not get network asset', uri: uri); } final Uint8List bytes = await consolidateHttpClientResponseBytes(response); From 7993bbde6a03a6abb5abac507940872f0c0ee984 Mon Sep 17 00:00:00 2001 From: Glenn Lewis <6598971+gmlewis@users.noreply.github.com> Date: Fri, 3 Aug 2018 20:55:46 -0400 Subject: [PATCH 138/512] Fix rounded rect when rx or ry is missing --- .../assets/simple/rect_rrect_no_ry.svg | 3 +++ third_party/example/main.dart | 1 + third_party/golden/simple/group_opacity.png | Bin 4140 -> 4140 bytes .../golden/simple/linear_gradient_2.png | Bin 745 -> 746 bytes third_party/golden/simple/radial_gradient.png | Bin 3285 -> 3286 bytes .../golden/simple/rect_rrect_no_ry.png | Bin 0 -> 2437 bytes third_party/lib/src/svg/xml_parsers.dart | 4 ++-- 7 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 third_party/assets/simple/rect_rrect_no_ry.svg create mode 100644 third_party/golden/simple/rect_rrect_no_ry.png diff --git a/third_party/assets/simple/rect_rrect_no_ry.svg b/third_party/assets/simple/rect_rrect_no_ry.svg new file mode 100644 index 000000000000..b98dd11995ca --- /dev/null +++ b/third_party/assets/simple/rect_rrect_no_ry.svg @@ -0,0 +1,3 @@ + + + diff --git a/third_party/example/main.dart b/third_party/example/main.dart index e2bccf44cd19..ce0ad1ec8578 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -19,6 +19,7 @@ const List assetNames = const [ 'assets/simple/linear_gradient_2.svg', 'assets/simple/radial_gradient.svg', 'assets/simple/rect_rrect.svg', + 'assets/simple/rect_rrect_no_ry.svg', 'assets/simple/style_attr.svg', 'assets/w3samples/aa.svg', 'assets/w3samples/alphachannel.svg', diff --git a/third_party/golden/simple/group_opacity.png b/third_party/golden/simple/group_opacity.png index d678309a7e1878b568a75ade36929502b006659d..26b9840ab8170cea75df8479407f9b8dac356f73 100644 GIT binary patch delta 3801 zcmV;~4kq!eAgmyeSu_v^9Gr>Rf)5&buP7-kRcRVu#ds`ILyr0$D*YL zHgC2+YoSnp$w~Y3?p>&>v;Y3aMlg)p#IVeoYuD!ITU%@Rjj0qII%I#AbL0pde>(>8 zcy(f!oP=Ng65f2X{5m^!z|VgUTeegu2C$F8sZ(~6IB95ro}TJf7~|u1Wp(>@`E?$D z+^#U9(dxu7H)kj4&70-dX=s3L+o~6XgR!w%C&<76Jpa7iVywin;GK8EFB~Hy@Ux%U zwdG108{vf);Hjs=jRD}*SKTX#f2ER1c=p-wV;CKU_usc`>y!o0VeJn0q2sZ|>e`l{T%+A{D7YgCWQAX_|*QrQrDS@M3uFe>H!F{lyo< zi{Z1+;M}>&w>x*v-Zm_L3j6KbFfyF_-G^_ulHb znVhr}#E+2?_wh<4{3J&h+b;FthwftzH$y}AAU>$MIqxm`a#K_A`RBo7@Srvc;x{?M z+8!3q5Utks3xfPDVZ|^$f4;igL-1~rpO(jm+9b&EaIozM2ZP5Dv}^GD-v^H&Xu+DA z3a4;ROa$BBZ_U5d!QDkKtFpa$o0oz!o5NCc~LPdw{ON>ueA5yIvpR zwSdE+mho}^JYb&w=J+_{0ng&>9`f0}x@Y`1lVq$wyC9ysOGBVCe?G+C zXd%d6hG-<{P<=D&2y%sKiUvMeVVzyOf+t8#x>zZKUCS7xD{u@$1iLam%J#r9j1#Qp zFHj$NA7R9CJy6lMe@)UDX!`>7fn)IE8<8MEw};>bJd6Z^V1LU9J3@&eXo7^1q(KY# z6t%eprzQzeQ-?6hQF}MkQH}BhT!;gPl z`F33l(#0T2QpCxT!6HSHLAt7v7*2LD!fuAx&M2F?e?cCD5q2=d?ohiDZW@@PgJCvs zo9)ZD&4`eWN9^AsmV?=t{oOe$^fKY5CJADZ z;SCPaMe(DvDHDFt4Of;QbL-xE`;WljaTpBeX2Bj#mE7M|h|V$E`A^KX-C+myT%~RC ze_~bJMf)?Ggo}Nl6pl_V(#Hu5@Z=DnveXAJoFm+V*q zGRe}%iTlZU-vb3`x(feO;Cx*(uWV^0AE{f6;mMaF)eEVfz%jt$-4sjBMrN69KMfmh z6UX2Z?Tc5@H(atma~53chUqH3Sa6A|f8T1-%K-n#^Ta8BGs($4@ce#{Uy@D2TkrU; zIZU#=#8DEYitX?2Fk`@f9)`5npi3R*6%KN`XjvgT$Lrs@ zLfR}&m^=noc#Jvfig)t6gLWJ~?dLp)d8H&lS$_)}$BGtZ>!Td~lgCImF1xxtf03}0 z)n|nfC&yp&7AD!E<#{8|M}Pbg)3NEI%*O2B!ll9p<5rWZjzKIkj>$1- zRgfHD*I?cLUn1AXiIU`4D45HW1E7_$(gGCC!;`PrO}-BYIbD(*0Oyn0lH>rp8@9Xv z0kHG5{m%!JtaEZi^CigvU>0V0f9ZoO7_)Q5|IwU=&J(_30O;mS$=@~`nRQGKfCTB1 zGDKt=66fviR~1z?LEhj{$sd-B!J%#+JF^C1&&i56JILwMt^{_$bV`l|ZCs^}Wd$Re z_f;@Vvh;AOWO>@m^WM%|Ww+bNt9JjjQ<=yce|fGwa?N$S7}L%zYCN+zHmQQDC5YpX0i0alq&? z2B(5K*6i(lGmf=4ES_QVXd9OumwSn$o-*q+JMXic8{TB{#MDrCL3yTaf zN?VD%QRX-=Q_{^^;IrH7Mb#3-sipw4 z>Yja1XXtv`+q%hA7R#Yr)q1jpSI3;iUDA2 z(+mZN$0WZ0cWF$Ie-D@a<*&0imBTFF66D(yupCYzc08K({CJy{$zeH^<${@~&eO4& zW}QO}F>>s2C=i$e;xmJ}p`NXf9YQ(%Ws(>-85oZ-T>^`r8lG^WQNK zwN^ChSSXUF$?@-dj3J)@hZoA{jHu@XiEWMI^g!J|{3LexxW^LibdD!8(47>;oy^A%hbcbI<6G)#nf7uzsOs|jAmYIglidXN-di4^d%*;^T0ZuqHt!t_*L6S+wgX%d!%KRV| z6$-GY4s+U%mpIBK>9&WQ_gPlLIp(Hy-rh1Zwy87@BWhH3EG!GBX47+mluIxp+}mH4 zs$PP0ciR(kF4LQ`yIFo5@AC1Ete(=_A`*pq4&2)4f3Wfr(I_-Gmn=@2Njlp)D~sW| z=Nyym@R)~N7#wbMFro&}J^5T^F?4o1R$9&V%`3Jd?>({6u?6Yr@NvtDL(js*V9)X^ z<;%rljxDhjw`kuGfX&eFaS-(HB@{W27FxG+4tx^j_f&7`GyA%Iu?xHtcf|} zQZU-uf9zRSmoTCReS7;VkHIt@6E&GP+!J-FDuSYxeb(?5}QZ9c@i*WjC2< zigLcwp^IoHIk@v+)>0&V?Iasf61ghN6C_TF{1NpN#+gy>%mF#b<3`p zx3gO-A)kj&ir-1Tb80=Gte+wqT{ciQ4A{CA))v=c2flTH z-ej-87!1R16^Dn5W{HZ{MX6g;$K*`$oE;NQQC>gr7!ys!6-lBw!O_1sTG<$ADa*2_ ze^JXXo+yd17K=D(CYWA+#XOOKhl^h|8jHl(pV(j3@yFz3t!BB+WT3aVWL~_K3BBDg z>{1yX+jq=g*UHJjfIaQ<68XA0UTz)Z-R23qzu(qY((g~2N&5Eoh11tfrQqn%qQU`i zdgColnOX8t>`G;0am!*FCVhMR{3qyAf7vXYI8id&RpF}wSHHMQ;j04gJ+YDVohF5K z#jR*hN00vmU2br&WOAfwW;suq6j?i=+uKW8Ju7a}-QMlL!t|*2(?BmAkW|W^chIsR zndHolc~bRvNM%#xrgJ3CP%7@AJIR```OM&-=bL&>Co({RQ?JoSJC;QK<`CsM}T!HTS>S zgd$oM-pp@= z!1Pg@jT8Z)O-9qq9!qcS1g?RM^Yib0YtI(Ew!Fre)wiR3GI|nObl%9=N#Xy|*mk`@ z74;~F+w>(ghi53(Rb-dhXy}Cw0~_pfnV8J?pK$kn#GFR&`5w5yEi8LK3a6w_5&R!Y zTs0R63c7sts?TC8e#`)X!Kmr`NF|d%lT8Dhn)oZ+FxdKsh`ncT-g6Glo~5dJiqb@? z-?)?%c=^0u&@Q*at)%_2f1fUcTL-^g`jUvgeO|E+t zK`Sh&+aIRk{Q=4Xvv_%SuQ~!~c#!Aps8UgX5*5Z>9IiM6=0Zh%p=8)8=RI;OIboQP zelqMZs-p#EiIIuij94JU;*U7BEy5E_c_pKou<)-d?r=JE8~!+FnTznwb$y4nyO=zi z!Lv>(@1C=)QY+G9=%u@8sgItbkrrwyl2qMr*#Lmqrq zF=C(EwLVUi5>ic=KyBZhbcs~&1RERx-r@zG1;T-9<22O6!?0GT?xtca-*miG1GN zR&JVwCz|+H#9OJm(C)QVG)h1R;(6xm(g&V@e)ties)K$izuzz_`Br_X7cZ(0>N;yg2;^18jk5`?Z6CIhS+I~Sl~BvZ>;cTKG;(#FGZ zKrRN0n&jOv`53X$ktWno;1N5wp>AHZNpjBs7*t$TwR$xb-;1)e=^PQ3fXH_W#Ml11 z;{rD_q+dy1&}`XPTw$=dOX}sCbl5?Tba(z48|QUcL1Z)UnIpyLUR@p$k-e62wUg>h z$Va?BJntAK_a)%BZvPFE?jL^_$+&1@{CIO-D6v9u)$^rk01>yzceXU1yB$FWh+at0 z068hf_34j?IfRlfY1nC=@(`2s|Le3~#$)0&ut(dsr%12wrrZH3M5(}2q!C1by zb-`w(h4L8WCGdTT&`Dy{%g9H}8MMUJpwHfF?TH26{{Y}ACm-Y^0GK9R+z3HSDQoAH zyK5`}mZ&kJ9BlEahc|V(l8sLz&m~B4J`xb6rAqrfpL_nCvPaU^k5LY+E0N-1C5Dcp z;2ue#FlM-|dCc$pkdn@iGGu9$Ea-oyXSjr`l$eC7Ajj(fa(ATTUOAK$=PeQdA~;2V zBnq1kW-n4UfJuW0&If0C`2f|+N| zV@l)CiE=(7uypR-y{Gc);Bs0N-huC`EHWLMYE-NY^AG|06rZD@2Z`tM$=!y2z0H(e zwc75}`{qr1tZ7rm5GSCnAL?ub8=tkbp zWZ%~Ie{&u8CZ-9z03z+Oj<&!qu6>#F=1LGL{XOA+3sXh!6+_%dK&<+!%2dgetkbH% zOI%PuqJibTG*t&q-+RJRoGa;isW5f<;u`Z%ZPPGS*Qcku+m$Yoh9r;-ED@&f`6LxD zk7@0f91&a1$3F;EVwrxs0=(G;tVEga@DjN}8|8N1Fb$f;!5O>I$2x!<50}=Yu8oF2 zd5!Y{+7>oH`eKu<|JY`tEPp*k+$>zw&Mcha`LMaSFE=IIxkKE{r^ybPL*$Iw-C6E| zF%#W^+5V;baEa0;6~d{H_%Q&Rfi{ge(f%2YT7bGGkxsv8?BoA5f8 zgvod7xziWMqE&FYcg;kyn#s@oo7``=7z~aY;!}c_GODNl4rL!@3-%9SYx$uw;10#w zTao|LrPNOsC^{6wsKJu(*#V1T4%|sGMa@^MauxhmdMTFx;jukBz#Vd8oOvi05LKvv zB(h@LF6eSOoPonHk0KDPq;JayxHL_<0dCy6JUCLYt^;i@Ak3xrVe&9iZQzpp^$RW; z5H2h_KgXaoNnO*CEj8k?f>=-jJoJ4}V*6;OpP?^vnWm|nziM0#^`~w`+uXJhT|Ob0 z%|^F@A%xZ4dQC5`-NKr%#<;@sOtX7p78T366a8ANc2;UH@GeJbvgSe+=A?=d#3r-T zIizD}Mg>01H89pC@}<&?zG~m$Xp>-{TdvLg>5Lt``(k5(Y?sxw563)!WMWWyIf-g_ zI@L6eGL2jq3vWF6KaEUfaO8R_WnI}J5*>;Jf>-PvD#S;n6=d;HVeG=v&v1xlv)aX9 zE4ru<t~tf#M4K2mToaP(ycss)3PuK$|yrwzh%f@Q4}xp zVdr{nhp!lBuk;~(|8>hKR%cu%>}Fa+{Mf%7!50A-{tExc(*|Z@Smu${+fx%N@UigWKyRaG zFL=-2?V-R-r;aP3D4{z5gOLue9Q|wp-AY1UbN-etYXkL-y!iv@d^5sPJ8$s5ZdP)q z4HV=UeE=S_6O{J^Dhm?d-8}kDKaT-X8ho^FMRn?j5S6{`j@f(9I48 zRRrYrImSj793jz=Z;7w%KRhMd=RrtU?NxH|s|bnY^W!>ig=OfHk2UJOa_EE}r$-r3 zVhqp@_iHSp&oPkdkUs01jH>N^cT^P8|9LL@Rq-Ja|El@LZTgk;3pa>_ISi1+tJ8VQ zz|B}+-qhRtR0ZEEXF;AHSgQ(d^SV;iBv;TW@gO{eB|C6D9DUzdY4ZBxz~RwLerGPWQ(1Ph`4lYQ12>>1#lX@LD}M2B z#Y$^m%+oY9uLkq!EPQM#uWaB&!X$*M7`*4V?=NnbRsb%gpv9I>|?nBDhr z>W7_&)`Yg|bW-OY;cYk_R8~Qw!{r6_1w`ZY&1$64q7&r-WAJa`-S~{hM}&ESfBGP!mOY%!*O zI}=aSzdcbKYEe^6lq57`U0en@tF{xPz*uWD0umi846Capv2K{8;q*P&|uY09DAQ8bk}3^SF5uQX*k~P`?@iH0<$(#Umr&n z?7D{dCorhQ;%i`*a=w_%C33#&?0mOmG1P^;oP_sMLTs6iO3QfS_7iE@!M{M$ZK7NF z{j&X{Wj%Sq#MZ!9WW%T&&jZ>+xZ}NGe~FNJN4}LCyT6mEYU{TC?yuZQuiTxp+HHa@ zEW|!csn4GJzQglWeb(A3T{d47@+Y}8J2eK>s2m~Q%UlMSE!I zb!q1`!gp_P`m5RRKS)jF+-w)_cYEb2h`xih4%hpd?hy}7bAu%3${JN)dkb2bpI^x# zud{MNyr{exwnH(}X8x<#gu-8;$d3m;A1kXXZ#~WYvGS|rnfVD|mId)bA5hFRQ`$>D zD1s1ytaj^zw@-KcxtlBbC0cxi#gkz+wJqoXlFcmqrhdJOqf+UeG-FLH%ZtPbU#UIU zVBZ=v!08M)I{qf!I5x;jzjFN2rzH>HD136W&}+HTLZ}Cfc0Mcl`}VH7X@wYe?rTfx z`Z&l6R>tUW-Qqhi!_)hTeE$1y>W7doL3bASx6CJ7Pm1sZw1>AAXh;8Ab+K2?Tl5=F zjH&&-F_3V%aESVSXxHuH!M&RF)a&nRlG8@q25x+Ra_xR@LgHz1)mKkt+XLQ{EI=g_ z@k4sq^^F{4AJ|Cf;ezvf$n bvBM*sTfJXQh|>LBe}TMaY5eBOz1aT%2VG_U diff --git a/third_party/golden/simple/linear_gradient_2.png b/third_party/golden/simple/linear_gradient_2.png index 4547d893b73f6665d158efb652154102ac263f39..a2f1a692cc593205e3d3c40032a98ebdcd774351 100644 GIT binary patch delta 410 zcmV;L0cHN_1?mNmK}wWKL_t(|obB8(ZWB=yhSB>XFCda@`YDj?9YC2f6?K-vQlOKpJ-`*?=QUum%=bE{}Z- zI6d2K)nd7s_z$hu>$<$WoOQ;F1oHLE=jzU9 z9MT@%x6#krKdkw6^Ki}h`6+v~y^SBS*CXb|`A<0e!FwHg_R+ctcXvPP;^M>W52UK< z;!V}3_cLwYTGd(GUEBD%J$RmaSEF?k@5b*Z-~C~Z^BsP^30GIQGyOsB0`nb{@c|W+ zzyU^+zyTj)VDS<|`fb(6Z*%QFRJE#V!|t)Q-E)nud-rX$_KBbS+g`udywn-e=Vm;^ z9KXK_eZQ^sdh+$NnLUuM>+1XWcXd1Wpyx1*uAHp%^S9M?-RyH(-w(rTHTxWRbv7H{ zK_C*7u>m#>u-I;Q|K0@HcYlBE6O*w5A(5a37{F`y6JGT+ndNCUEdT%j07*qoM6N<$ Ef>NZ}2LJ#7 delta 406 zcmV;H0crl~1?dHlK}nNIL_t(|obB8(P8(4ahSB?w7l7QSpCXdIgQTRSO3hNTl%!2X znF_IiNaK!@4cKA_lfqGiNAaIv7;Kbtnwepq-+e-Sg&V4qu>v8HpamR&!?l~6VVKX4 zeGE7~>vh#^KCfCVj(rq3J*!ob%|3r@>H*i+*VXs^)MNM$Etku>yu6%r#;XMK{oB{- z&L-M}Gzu)`r4|AOF@bm3)b#*(@AJhXb-$9eX z0Y#I*0X1S~uQ8-wSAG65)$T)8tEx6^A6wf#*XX))-$rYn`MJOC^?S{0ogsa0!ZS?q z``e@M*R@>kef?r452Wk5y1)NWw^I*#3B%~h$vQuOUtQNtKBx8lFf106&w)2*welSV zB9pNJHw?4QX8Z3=fL)u-u}_n+0wIy01{ZJLPx*{AnPbI)NdN!<07*qoM6N<$f=Auj A)Bpeg diff --git a/third_party/golden/simple/radial_gradient.png b/third_party/golden/simple/radial_gradient.png index 20e8b9999a1e54ca1ff270a1c83370310480f3c3..68361b211ef40b6a496d5665a053c6695bddb21a 100644 GIT binary patch delta 149 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 Date: Wed, 8 Aug 2018 14:10:42 -0400 Subject: [PATCH 139/512] Fix painting inheritence --- third_party/CHANGELOG.md | 6 + third_party/example/main.dart | 9 +- .../golden/simple/group_fill_opacity.png | Bin 6418 -> 6546 bytes .../golden/wikimedia/Ghostscript_Tiger.png | Bin 47211 -> 44393 bytes third_party/lib/src/avd/xml_parsers.dart | 45 ++-- third_party/lib/src/avd_parser.dart | 8 +- third_party/lib/src/svg/xml_parsers.dart | 103 ++++---- third_party/lib/src/svg_parser.dart | 11 +- third_party/lib/src/vector_drawable.dart | 221 ++++++++++++++---- third_party/pubspec.lock | 6 +- third_party/pubspec.yaml | 6 +- 11 files changed, 269 insertions(+), 146 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 69246dee9f7d..b36cda6d2856 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGES +## 0.5.5 + +- Create a new class to encapsulate `Paint` and assist with inheriting all painting properties. +- Fixes regression introduced in v0.5.2 where some previously working inheritence stopped working. +- Support more complex stroke/fill property inheritence. + ## 0.5.4 - Consume latest path_drawing (and path_parsing) packages to fix issue(s) with smooth curve handling. diff --git a/third_party/example/main.dart b/third_party/example/main.dart index ce0ad1ec8578..62d2098b6436 100644 --- a/third_party/example/main.dart +++ b/third_party/example/main.dart @@ -85,7 +85,14 @@ class _MyHomePageState extends State { _dimension = 250.0; _painters.add(new SvgPicture.string( - '')); + ''' + + + + + + +''')); for (String assetName in assetNames) { _painters.add( diff --git a/third_party/golden/simple/group_fill_opacity.png b/third_party/golden/simple/group_fill_opacity.png index 3905d45aa9a62b38af3017af90f79a5e99c97324..3cb70c6522d9a12441cbc065a40553180868b276 100644 GIT binary patch literal 6546 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 literal 6418 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 diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index 0386e526bd3e..49d21902cd06 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -1,6 +1,7 @@ import 'dart:math'; import 'dart:ui'; +import 'package:flutter_svg/src/vector_drawable.dart'; import 'package:vector_math/vector_math_64.dart'; import 'package:xml/xml.dart'; @@ -24,8 +25,8 @@ Rect parseViewBox(XmlElement el) { } Matrix4 parseTransform(XmlElement el) { - final double rotation = double - .parse(getAttribute(el, 'rotation', def: '0', namespace: androidNS)); + final double rotation = double.parse( + getAttribute(el, 'rotation', def: '0', namespace: androidNS)); final double pivotX = double.parse(getAttribute(el, 'pivotX', def: '0', namespace: androidNS)); final double pivotY = @@ -34,10 +35,10 @@ Matrix4 parseTransform(XmlElement el) { double.parse(getAttribute(el, 'scaleX', def: '1', namespace: androidNS)); final double scaleY = double.parse(getAttribute(el, 'scaleY', def: '1', namespace: androidNS)); - final double translateX = double - .parse(getAttribute(el, 'translateX', def: '0', namespace: androidNS)); - final double translateY = double - .parse(getAttribute(el, 'translateY', def: '0', namespace: androidNS)); + final double translateX = double.parse( + getAttribute(el, 'translateX', def: '0', namespace: androidNS)); + final double translateY = double.parse( + getAttribute(el, 'translateY', def: '0', namespace: androidNS)); return new Matrix4.identity() ..translate(pivotX, pivotY) @@ -46,21 +47,22 @@ Matrix4 parseTransform(XmlElement el) { ..translate(-pivotX + translateX, -pivotY + translateY); } -Paint parseStroke(XmlElement el, Rect bounds) { +DrawablePaint parseStroke(XmlElement el, Rect bounds) { final String rawStroke = getAttribute(el, 'strokeColor', def: null, namespace: androidNS); if (rawStroke == null) { return null; } - return new Paint() - ..style = PaintingStyle.stroke - ..color = parseColor(rawStroke).withOpacity(double - .parse(getAttribute(el, 'strokeAlpha', def: '1', namespace: androidNS))) - ..strokeWidth = double - .parse(getAttribute(el, 'strokeWidth', def: '0', namespace: androidNS)) - ..strokeCap = parseStrokeCap(el) - ..strokeJoin = parseStrokeJoin(el) - ..strokeMiterLimit = parseMiterLimit(el); + return new DrawablePaint( + PaintingStyle.stroke, + color: parseColor(rawStroke).withOpacity(double.parse( + getAttribute(el, 'strokeAlpha', def: '1', namespace: androidNS))), + strokeWidth: double.parse( + getAttribute(el, 'strokeWidth', def: '0', namespace: androidNS)), + strokeCap: parseStrokeCap(el), + strokeJoin: parseStrokeJoin(el), + strokeMiterLimit: parseMiterLimit(el), + ); } double parseMiterLimit(XmlElement el) { @@ -98,16 +100,17 @@ StrokeCap parseStrokeCap(XmlElement el) { } } -Paint parseFill(XmlElement el, Rect bounds) { +DrawablePaint parseFill(XmlElement el, Rect bounds) { final String rawFill = getAttribute(el, 'fillColor', def: null, namespace: androidNS); if (rawFill == null) { return null; } - return new Paint() - ..style = PaintingStyle.fill - ..color = parseColor(rawFill) - .withOpacity(double.parse(getAttribute(el, 'fillAlpha', def: '1'))); + return new DrawablePaint( + PaintingStyle.fill, + color: parseColor(rawFill) + .withOpacity(double.parse(getAttribute(el, 'fillAlpha', def: '1'))), + ); } PathFillType parsePathFillType(XmlElement el) { diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index e324196eba21..29c69de914f7 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -26,8 +26,8 @@ class DrawableAvdPath extends DrawableShape { assert(path != null); path.fillType = parsePathFillType(el); - final Paint stroke = parseStroke(el, path.getBounds()); - final Paint fill = parseFill(el, path.getBounds()); + final DrawablePaint stroke = parseStroke(el, path.getBounds()); + final DrawablePaint fill = parseFill(el, path.getBounds()); return new DrawableAvdPath( path, @@ -64,8 +64,8 @@ Drawable parseAvdGroup(XmlElement el, Rect bounds) { final Matrix4 transform = parseTransform(el); - final Paint fill = parseFill(el, bounds); - final Paint stroke = parseStroke(el, bounds); + final DrawablePaint fill = parseFill(el, bounds); + final DrawablePaint stroke = parseStroke(el, bounds); return new DrawableGroup( children, diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 9ef65baf42ff..b213091cf963 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -135,15 +135,13 @@ PaintServer parseLinearGradient(XmlElement el) { bounds.left + (bounds.height * y2), ); - final Gradient gradient = new Gradient.linear( + return new Gradient.linear( from, to, colors, offsets, spreadMethod, ); - - return new Paint()..shader = gradient; }; } @@ -185,7 +183,7 @@ PaintServer parseRadialGradient(XmlElement el) { final Offset focal = (fx != cx || fy != cy) ? new Offset(fx, fy) : new Offset(cx, cy); - final Gradient gradient = new Gradient.radial( + return new Gradient.radial( center, r, colors, @@ -195,8 +193,6 @@ PaintServer parseRadialGradient(XmlElement el) { focal, 0.0, ); - - return new Paint()..shader = gradient; }; } @@ -288,27 +284,11 @@ double parseOpacity(XmlElement el) { return null; } -Paint _changePaintColor(Paint src, Color newColor) { - return new Paint() - ..blendMode = src.blendMode - ..color = newColor - ..colorFilter = src.colorFilter - ..filterQuality = src.filterQuality - ..isAntiAlias = src.isAntiAlias - ..maskFilter = src.maskFilter - ..shader = src.shader - ..strokeCap = src.strokeCap - ..strokeJoin = src.strokeJoin - ..strokeMiterLimit = src.strokeMiterLimit - ..strokeWidth = src.strokeWidth - ..style = src.style; -} - -Paint _getDefinitionPaint( - String iri, DrawableDefinitionServer definitions, Rect bounds, +DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri, + DrawableDefinitionServer definitions, Rect bounds, {double opacity}) { - final Paint paint = definitions.getPaint(iri, bounds); - if (paint == null) { + final Shader shader = definitions.getPaint(iri, bounds); + if (shader == null) { FlutterError.onError( new FlutterErrorDetails( exception: new StateError('Failed to find definition for $iri'), @@ -325,14 +305,15 @@ Paint _getDefinitionPaint( ), ); } - if (opacity != null) { - return _changePaintColor(paint, paint.color.withOpacity(opacity)); - } - return paint; + return new DrawablePaint( + paintingStyle, + shader: shader, + color: opacity != null ? new Color.fromRGBO(255, 255, 255, opacity) : null, + ); } /// Parses a @stroke attribute into a [Paint]. -Paint parseStroke(XmlElement el, Rect bounds, +DrawablePaint parseStroke(XmlElement el, Rect bounds, DrawableDefinitionServer definitions, Color defaultStrokeIfNotSpecified) { final String rawStroke = getAttribute(el, 'stroke'); final String rawOpacity = getAttribute(el, 'stroke-opacity'); @@ -344,47 +325,43 @@ Paint parseStroke(XmlElement el, Rect bounds, if (defaultStrokeIfNotSpecified == null) { return null; } - return new Paint() - ..style = PaintingStyle.stroke - ..color = defaultStrokeIfNotSpecified.withOpacity(opacity); + return new DrawablePaint(PaintingStyle.stroke, + color: defaultStrokeIfNotSpecified.withOpacity(opacity)); } else if (rawStroke == 'none') { - return DrawableStyle.emptyPaint; + return DrawablePaint.empty; } if (rawStroke.startsWith('url')) { - return _getDefinitionPaint(rawStroke, definitions, bounds, + return _getDefinitionPaint( + PaintingStyle.stroke, rawStroke, definitions, bounds, opacity: opacity); } - final Paint paint = new Paint() - ..color = parseColor(rawStroke).withOpacity(opacity) - ..style = PaintingStyle.stroke; - final String rawStrokeCap = getAttribute(el, 'stroke-linecap'); - paint.strokeCap = rawStrokeCap == 'null' - ? StrokeCap.butt - : StrokeCap.values.firstWhere( - (StrokeCap sc) => sc.toString() == 'StrokeCap.$rawStrokeCap', - orElse: () => StrokeCap.butt); - final String rawLineJoin = getAttribute(el, 'stroke-linejoin'); - paint.strokeJoin = rawLineJoin == '' - ? StrokeJoin.miter - : StrokeJoin.values.firstWhere( - (StrokeJoin sj) => sj.toString() == 'StrokeJoin.$rawLineJoin', - orElse: () => StrokeJoin.miter); - final String rawMiterLimit = getAttribute(el, 'stroke-miterlimit'); - paint.strokeMiterLimit = - rawMiterLimit == '' ? 4.0 : double.parse(rawMiterLimit); - final String rawStrokeWidth = getAttribute(el, 'stroke-width'); - paint.strokeWidth = rawStrokeWidth == '' ? 1.0 : double.parse(rawStrokeWidth); + final DrawablePaint paint = new DrawablePaint( + PaintingStyle.stroke, + color: parseColor(rawStroke).withOpacity(opacity), + strokeCap: rawStrokeCap == 'null' + ? StrokeCap.butt + : StrokeCap.values.firstWhere( + (StrokeCap sc) => sc.toString() == 'StrokeCap.$rawStrokeCap', + orElse: () => StrokeCap.butt), + strokeJoin: rawLineJoin == '' + ? StrokeJoin.miter + : StrokeJoin.values.firstWhere( + (StrokeJoin sj) => sj.toString() == 'StrokeJoin.$rawLineJoin', + orElse: () => StrokeJoin.miter), + strokeMiterLimit: rawMiterLimit == '' ? 4.0 : double.parse(rawMiterLimit), + strokeWidth: rawStrokeWidth == '' ? 1.0 : double.parse(rawStrokeWidth), + ); return paint; } -Paint parseFill(XmlElement el, Rect bounds, +DrawablePaint parseFill(XmlElement el, Rect bounds, DrawableDefinitionServer definitions, Color defaultFillIfNotSpecified) { final String rawFill = getAttribute(el, 'fill'); final String rawOpacity = getAttribute(el, 'fill-opacity'); @@ -396,20 +373,20 @@ Paint parseFill(XmlElement el, Rect bounds, if (defaultFillIfNotSpecified == null) { return null; } - return new Paint()..color = defaultFillIfNotSpecified.withOpacity(opacity); + return new DrawablePaint(PaintingStyle.fill, + color: defaultFillIfNotSpecified.withOpacity(opacity)); } else if (rawFill == 'none') { - return DrawableStyle.emptyPaint; + return DrawablePaint.empty; } if (rawFill.startsWith('url')) { - return _getDefinitionPaint(rawFill, definitions, bounds, opacity: opacity); + return _getDefinitionPaint(PaintingStyle.fill, rawFill, definitions, bounds, + opacity: opacity); } final Color fill = parseColor(rawFill).withOpacity(opacity); - return new Paint() - ..color = fill - ..style = PaintingStyle.fill; + return new DrawablePaint(PaintingStyle.fill, color: fill); } PathFillType parseFillRule(XmlElement el, diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 1dd8ef33286a..bc486fc89aae 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -24,17 +24,15 @@ class DrawableSvgShape extends DrawableShape { final Color defaultFill = parentStyle == null || parentStyle.fill == null ? colorBlack - : identical(parentStyle.fill, DrawableStyle.emptyPaint) + : identical(parentStyle.fill, DrawablePaint.empty) ? null : parentStyle.fill.color; final Color defaultStroke = - identical(parentStyle.stroke, DrawableStyle.emptyPaint) + identical(parentStyle.stroke, DrawablePaint.empty) ? null : parentStyle?.stroke?.color; - // print(defaultStroke); - final Path path = pathFactory(el); return new DrawableSvgShape( applyTransformIfNeeded(path, el), @@ -103,11 +101,11 @@ Paint _transparentPaint = new Paint()..color = const Color(0x0); void _appendParagraphs(ParagraphBuilder fill, ParagraphBuilder stroke, String text, DrawableStyle style) { fill - ..pushStyle(style.textStyle.buildTextStyle(foregroundOverride: style.fill)) + ..pushStyle(style.textStyle.toFlutterTextStyle(foregroundOverride: style.fill)) ..addText(text); stroke - ..pushStyle(style.textStyle.buildTextStyle( + ..pushStyle(style.textStyle.toFlutterTextStyle( foregroundOverride: style.stroke == null ? _transparentPaint : style.stroke)) ..addText(text); @@ -133,7 +131,6 @@ void _paragraphParser( switch (child.nodeType) { case XmlNodeType.CDATA: case XmlNodeType.TEXT: - // print(style.stroke); _appendParagraphs(fill, stroke, child.text, style); break; case XmlNodeType.ELEMENT: diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 477d359a90f1..9f71dbc39873 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -7,7 +7,7 @@ import 'package:path_drawing/path_drawing.dart'; import 'render_picture.dart' as render_picture; -typedef Paint PaintServer(Rect bounds); +typedef Shader PaintServer(Rect bounds); /// Base interface for vector drawing. @immutable @@ -25,13 +25,6 @@ abstract class Drawable { /// Contains [Paint], [Path], dashing, transform, and text styling information. @immutable class DrawableStyle { - /// This should be used where 'stroke' or 'fill' are 'none'. - /// - /// This will not result in a drawing operation, but will clear out - /// inheritance. Modifying this paint should not result in any changes to - /// the image, but it should not be modified. - static final Paint emptyPaint = new Paint()..color = const Color(0x00000000); - /// Used where 'dasharray' is 'none' /// /// This will not result in a drawing operation, but will clear out @@ -39,9 +32,9 @@ class DrawableStyle { static final CircularIntervalList emptyDashArray = new CircularIntervalList(const []); - /// If not `null` and not `identical` with [emptyPaint], will result in a stroke + /// If not `null` and not `identical` with [DrawablePaint.empty], will result in a stroke /// for the rendered [DrawableShape]. Drawn __after__ the [fill]. - final Paint stroke; + final DrawablePaint stroke; /// The dashing array to use for the [stroke], if any. final CircularIntervalList dashArray; @@ -49,9 +42,9 @@ class DrawableStyle { /// The [DashOffset] to use for where to begin the [dashArray]. final DashOffset dashOffset; - /// If not `null` and not `identical` with [emptyPaint], will result in a fill + /// If not `null` and not `identical` with [DrawablePaint.empty], will result in a fill /// for the rendered [DrawableShape]. Drawn __before__ the [stroke]. - final Paint fill; + final DrawablePaint fill; /// The 4x4 matrix ([Matrix4]) for a transform, if any. final Float64List transform; @@ -81,8 +74,8 @@ class DrawableStyle { /// Creates a new [DrawableStyle] if `parent` is not null, filling in any null properties on /// this with the properties from other (except [groupOpacity], which is averaged). static DrawableStyle mergeAndBlend(DrawableStyle parent, - {Paint fill, - Paint stroke, + {DrawablePaint fill, + DrawablePaint stroke, CircularIntervalList dashArray, DashOffset dashOffset, Float64List transform, @@ -90,9 +83,10 @@ class DrawableStyle { PathFillType pathFillType, double groupOpacity, List clipPath}) { - final DrawableStyle ret = new DrawableStyle( - fill: fill ?? parent?.fill, - stroke: stroke ?? parent?.stroke, + groupOpacity = mergeOpacity(groupOpacity, parent?.groupOpacity); + return new DrawableStyle( + fill: new DrawablePaint.merge(fill, parent?.fill, groupOpacity), + stroke: new DrawablePaint.merge(stroke, parent?.stroke, groupOpacity), dashArray: dashArray ?? parent?.dashArray, dashOffset: dashOffset ?? parent?.dashOffset, // transforms aren't inherited because they're applied to canvas with save/restore @@ -100,25 +94,11 @@ class DrawableStyle { transform: transform, textStyle: new DrawableTextStyle.merge(textStyle, parent?.textStyle), pathFillType: pathFillType ?? parent?.pathFillType, - groupOpacity: mergeOpacity(groupOpacity, parent?.groupOpacity), + groupOpacity: groupOpacity, // clips don't make sense to inherit - applied to canvas with save/restore // that wraps any potential children clipPath: clipPath, ); - - if (ret.fill != null) { - ret.fill.color = ret.fill.color.withOpacity(ret.fill.color.opacity == 1.0 - ? ret.groupOpacity ?? 1.0 - : mergeOpacity(ret.groupOpacity, ret.fill.color.opacity)); - } - if (ret.stroke != null) { - ret.stroke.color = ret.stroke.color.withOpacity( - ret.stroke.color.opacity == 1.0 - ? ret.groupOpacity ?? 1.0 - : mergeOpacity(ret.groupOpacity, ret.stroke.color.opacity)); - } - - return ret; } /// Averages [back] and [front]. If either is null, returns the other. @@ -139,6 +119,161 @@ class DrawableStyle { } } +/// A wrapper class for Flutter's [Paint] class. +/// +/// Provides non-opaque access to painting properties. +@immutable +class DrawablePaint { + const DrawablePaint( + this.style, { + this.color, + this.shader, + this.blendMode, + this.colorFilter, + this.isAntiAlias, + this.filterQuality, + this.maskFilter, + this.strokeCap, + this.strokeJoin, + this.strokeMiterLimit, + this.strokeWidth, + }); + + /// Will merge two DrawablePaints, preferring properties defined in `a` if they're not null. + /// + /// If `a` is `identical` wiht [DrawablePaint.empty], `b` will be ignored. + factory DrawablePaint.merge(DrawablePaint a, DrawablePaint b, + [double groupOpacity]) { + if (a == null && b == null) { + return null; + } + + if (b == null && a != null) { + return a._withGroupOpacity(groupOpacity); + } + + if (identical(a, DrawablePaint.empty) || identical(b, DrawablePaint.empty)) { + return a; + } + + if (a == null) { + return b._withGroupOpacity(groupOpacity); + } + + // If we got here, the styles should not be null. + assert( + a.style == b.style, 'Cannot merge Paints with different PaintStyles; got:\na: $a\nb: $b.'); + + final Color mergedColor = a.color ?? b.color; + + return new DrawablePaint( + a.style ?? b.style, + color: mergedColor.withOpacity(mergedColor.opacity == 1.0 + ? groupOpacity ?? 1.0 + : DrawableStyle.mergeOpacity(groupOpacity, mergedColor.opacity)), + shader: a.shader ?? b.shader, + blendMode: a.blendMode ?? b.blendMode, + colorFilter: a.colorFilter ?? b.colorFilter, + isAntiAlias: a.isAntiAlias ?? b.isAntiAlias, + filterQuality: a.filterQuality ?? b.filterQuality, + maskFilter: a.maskFilter ?? b.maskFilter, + strokeCap: a.strokeCap ?? b.strokeCap, + strokeJoin: a.strokeJoin ?? b.strokeJoin, + strokeMiterLimit: a.strokeMiterLimit ?? b.strokeMiterLimit, + strokeWidth: a.strokeWidth ?? b.strokeWidth, + ); + } + + static const DrawablePaint empty = const DrawablePaint(null); + + final Color color; + final Shader shader; + final BlendMode blendMode; + final ColorFilter colorFilter; + final bool isAntiAlias; + final FilterQuality filterQuality; + final MaskFilter maskFilter; + final PaintingStyle style; + final StrokeCap strokeCap; + final StrokeJoin strokeJoin; + final double strokeMiterLimit; + final double strokeWidth; + + DrawablePaint _withGroupOpacity(double groupOpacity) { + if (color == null || groupOpacity == null) { + return this; + } + return new DrawablePaint.merge( + new DrawablePaint( + style, + color: color.withOpacity( + color.opacity == 1.0 + ? groupOpacity ?? 1.0 + : DrawableStyle.mergeOpacity(groupOpacity, color.opacity), + ), + ), + this, + ); + } + + @virtual + Paint toFlutterPaint([ColorFilter colorFilterOverride]) { + final Paint paint = new Paint(); + + // unfortunately, need to nullcheck all of these + if (blendMode != null) { + paint.blendMode = blendMode; + } + if (color != null) { + paint.color = color; + } + if (colorFilterOverride != null || colorFilter != null) { + paint.colorFilter = colorFilterOverride ?? colorFilter; + } + if (filterQuality != null) { + paint.filterQuality = filterQuality; + } + if (isAntiAlias != null) { + paint.isAntiAlias = isAntiAlias; + } + if (maskFilter != null) { + paint.maskFilter = maskFilter; + } + if (shader != null) { + paint.shader = shader; + } + if (strokeCap != null) { + paint.strokeCap = strokeCap; + } + if (strokeJoin != null) { + paint.strokeJoin = strokeJoin; + } + if (strokeMiterLimit != null) { + paint.strokeMiterLimit = strokeMiterLimit; + } + if (strokeWidth != null) { + paint.strokeWidth = strokeWidth; + } + if (style != null) { + paint.style = style; + } + + return paint; + } + + @override + String toString() { + return 'DrawablePaint{$style, color: $color, shader: $shader, blendMode: $blendMode, ' + 'colorFilter: $colorFilter, isAntiAlias: $isAntiAlias, filterQuality: $filterQuality, ' + 'maskFilter: $maskFilter, strokeCap: $strokeCap, strokeJoin: $strokeJoin, ' + 'strokeMiterLimit: $strokeMiterLimit, strokeWidth: $strokeWidth}'; + } +} + +/// A wrapper class for Flutter's [TextStyle] class. +/// +/// Provides non-opaque access to text styling properties. +@immutable class DrawableTextStyle { const DrawableTextStyle({ this.decoration, @@ -197,7 +332,7 @@ class DrawableTextStyle { final Paint background; final Paint foreground; - TextStyle buildTextStyle({Paint foregroundOverride}) { + TextStyle toFlutterTextStyle({DrawablePaint foregroundOverride}) { return new TextStyle( decoration: decoration, decorationColor: decorationColor, @@ -284,7 +419,7 @@ class DrawableDefinitionServer { /// Attempt to lookup a pre-defined [Paint] by [id]. /// /// [id] and [bounds] must not be null. - Paint getPaint(String id, Rect bounds) { + Shader getPaint(String id, Rect bounds) { assert(id != null); assert(bounds != null); final PaintServer srv = _paintServers[id]; @@ -435,7 +570,7 @@ class DrawableGroup implements Drawable { canvas.clipPath(clipPath); if (children.length > 1) { - canvas.saveLayer(clipPath.getBounds(), DrawableStyle.emptyPaint); + canvas.saveLayer(clipPath.getBounds(), new Paint()); } innerDraw(); @@ -479,25 +614,23 @@ class DrawableShape implements Drawable { // if we have multiple clips to apply, need to wrap this in a loop. final Function innerDraw = () { - if (style.fill != null && - !identical(style.fill, DrawableStyle.emptyPaint)) { + if (style.fill?.style != null) { assert(style.fill.style == PaintingStyle.fill); - style.fill.colorFilter = colorFilter; - canvas.drawPath(path, style.fill); + // style.fill.colorFilter = colorFilter; + canvas.drawPath(path, style.fill.toFlutterPaint(colorFilter)); } - if (style.stroke != null && - !identical(style.stroke, DrawableStyle.emptyPaint)) { + if (style.stroke?.style != null) { assert(style.stroke.style == PaintingStyle.stroke); - style.stroke.colorFilter = colorFilter; + // style.stroke.colorFilter = colorFilter; if (style.dashArray != null && !identical(style.dashArray, DrawableStyle.emptyDashArray)) { canvas.drawPath( dashPath(path, dashArray: style.dashArray, dashOffset: style.dashOffset), - style.stroke); + style.stroke.toFlutterPaint(colorFilter)); } else { - canvas.drawPath(path, style.stroke); + canvas.drawPath(path, style.stroke.toFlutterPaint(colorFilter)); } } }; diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index d6dbe787d5aa..c89daccfa73e 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -234,7 +234,7 @@ packages: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "1.7.7" + version: "2.0.0" plugin: dependency: transitive description: @@ -400,7 +400,7 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "3.2.0" yaml: dependency: transitive description: @@ -409,5 +409,5 @@ packages: source: hosted version: "2.1.15" sdks: - dart: ">=2.0.0-dev.62.0 <=2.0.0-dev.69.4.flutter-08f59e5de3" + dart: ">=2.0.0-dev.69.0 <=2.0.0-dev.69.5.flutter-b04def964c" flutter: ">=0.5.1 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 3c8a7dd99d84..996c16673197 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,11 +2,11 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.5.4 +version: 0.5.5 dependencies: path_drawing: ^0.3.0 - xml: ^3.0.0 + xml: ^3.2.0 vector_math: ^2.0.4 meta: ^1.1.2 flutter: @@ -15,7 +15,7 @@ dependencies: dev_dependencies: mockito: ^2.2.3 path: ^1.5.1 - test: ^0.12.34 + test: ^0.12.41 flutter_test: sdk: flutter From 3b3b23ecafcdbdc15684ca04c37e2322fbaa85f2 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 8 Aug 2018 14:43:28 -0400 Subject: [PATCH 140/512] fix for flutter beta channel --- third_party/pubspec.lock | 110 +++++++++++++++++---------------------- third_party/pubspec.yaml | 6 +-- 2 files changed, 51 insertions(+), 65 deletions(-) diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index c89daccfa73e..cff085483115 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -7,35 +7,35 @@ packages: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.32.4" + version: "0.31.2-alpha.2" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.4.4" + version: "1.4.3" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.0.7" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.0.3" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.2" + version: "1.1.1" collection: dependency: transitive description: @@ -49,21 +49,21 @@ packages: name: convert url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.1" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.0.6" + version: "2.0.3" csslib: dependency: transitive description: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.14.4+1" + version: "0.14.4" flutter: dependency: "direct main" description: flutter @@ -80,77 +80,70 @@ packages: name: front_end url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.0-alpha.12" glob: dependency: transitive description: name: glob url: "https://pub.dartlang.org" source: hosted - version: "1.1.7" + version: "1.1.5" html: dependency: transitive description: name: html url: "https://pub.dartlang.org" source: hosted - version: "0.13.3+2" + version: "0.13.3" http: dependency: transitive description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.11.3+17" + version: "0.11.3+16" http_multi_server: dependency: transitive description: name: http_multi_server url: "https://pub.dartlang.org" source: hosted - version: "2.0.5" + version: "2.0.4" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.3" + version: "3.1.2" io: dependency: transitive description: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.3" + version: "0.3.2+1" js: dependency: transitive description: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.1+1" - json_rpc_2: - dependency: transitive - description: - name: json_rpc_2 - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.9" + version: "0.6.1" kernel: dependency: transitive description: name: kernel url: "https://pub.dartlang.org" source: hosted - version: "0.3.4" + version: "0.3.0-alpha.12" logging: dependency: transitive description: name: logging url: "https://pub.dartlang.org" source: hosted - version: "0.11.3+2" + version: "0.11.3+1" matcher: dependency: transitive description: @@ -171,7 +164,7 @@ packages: name: mime url: "https://pub.dartlang.org" source: hosted - version: "0.9.6+2" + version: "0.9.6" mockito: dependency: "direct dev" description: @@ -185,35 +178,35 @@ packages: name: multi_server_socket url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.0.1" node_preamble: dependency: transitive description: name: node_preamble url: "https://pub.dartlang.org" source: hosted - version: "1.4.4" + version: "1.4.1" package_config: dependency: transitive description: name: package_config url: "https://pub.dartlang.org" source: hosted - version: "1.0.5" + version: "1.0.3" package_resolver: dependency: transitive description: name: package_resolver url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.0.2" path: dependency: "direct dev" description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.6.2" + version: "1.5.1" path_drawing: dependency: "direct main" description: @@ -234,63 +227,63 @@ packages: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "1.7.7" plugin: dependency: transitive description: name: plugin url: "https://pub.dartlang.org" source: hosted - version: "0.2.0+3" + version: "0.2.0+2" pool: dependency: transitive description: name: pool url: "https://pub.dartlang.org" source: hosted - version: "1.3.6" + version: "1.3.4" pub_semver: dependency: transitive description: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.4.2" + version: "1.4.1" quiver: dependency: transitive description: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "2.0.0+1" + version: "0.29.0+1" shelf: dependency: transitive description: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "0.7.3+3" + version: "0.7.3" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.0.3" shelf_static: dependency: transitive description: name: shelf_static url: "https://pub.dartlang.org" source: hosted - version: "0.2.8" + version: "0.2.7" shelf_web_socket: dependency: transitive description: name: shelf_web_socket url: "https://pub.dartlang.org" source: hosted - version: "0.2.2+3" + version: "0.2.2" sky_engine: dependency: transitive description: flutter @@ -302,56 +295,56 @@ packages: name: source_map_stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.1.5" + version: "1.1.4" source_maps: dependency: transitive description: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.7" + version: "0.10.5" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.4.1" + version: "1.4.0" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.9.2" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "1.6.8" + version: "1.6.6" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.2" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.0" test: dependency: "direct dev" description: name: test url: "https://pub.dartlang.org" source: hosted - version: "0.12.41" + version: "0.12.37" typed_data: dependency: transitive description: @@ -365,49 +358,42 @@ packages: name: utf url: "https://pub.dartlang.org" source: hosted - version: "0.9.0+5" + version: "0.9.0+4" vector_math: dependency: "direct main" description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" - vm_service_client: - dependency: transitive - description: - name: vm_service_client - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.6" + version: "2.0.6" watcher: dependency: transitive description: name: watcher url: "https://pub.dartlang.org" source: hosted - version: "0.9.7+10" + version: "0.9.7+7" web_socket_channel: dependency: transitive description: name: web_socket_channel url: "https://pub.dartlang.org" source: hosted - version: "1.0.9" + version: "1.0.7" xml: dependency: "direct main" description: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.2.0" + version: "3.0.0" yaml: dependency: transitive description: name: yaml url: "https://pub.dartlang.org" source: hosted - version: "2.1.15" + version: "2.1.13" sdks: - dart: ">=2.0.0-dev.69.0 <=2.0.0-dev.69.5.flutter-b04def964c" + dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.58.0.flutter-f981f09760" flutter: ">=0.5.1 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 996c16673197..34fa96d8f56e 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,11 +2,11 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.5.5 +version: 0.5.5+1 dependencies: path_drawing: ^0.3.0 - xml: ^3.2.0 + xml: 3.0.0 vector_math: ^2.0.4 meta: ^1.1.2 flutter: @@ -15,7 +15,7 @@ dependencies: dev_dependencies: mockito: ^2.2.3 path: ^1.5.1 - test: ^0.12.41 + test: 0.12.37 flutter_test: sdk: flutter From fdb9cbbfd166a667c64fa3e83571db667783bab5 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 8 Aug 2018 14:44:11 -0400 Subject: [PATCH 141/512] adjust pubspec --- third_party/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 34fa96d8f56e..8d9f070d0f70 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -6,7 +6,7 @@ version: 0.5.5+1 dependencies: path_drawing: ^0.3.0 - xml: 3.0.0 + xml: ^3.0.0 vector_math: ^2.0.4 meta: ^1.1.2 flutter: @@ -15,7 +15,7 @@ dependencies: dev_dependencies: mockito: ^2.2.3 path: ^1.5.1 - test: 0.12.37 + test: ^0.12.37 flutter_test: sdk: flutter From 8a306a4b72fc8a30e8307cf2a87df251e01efb5f Mon Sep 17 00:00:00 2001 From: Stefano Rodriguez Date: Fri, 7 Sep 2018 14:00:10 +0200 Subject: [PATCH 142/512] Fix merge style edge case --- third_party/assets/simple/opacity_on_path.svg | 3 +++ third_party/lib/src/vector_drawable.dart | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 third_party/assets/simple/opacity_on_path.svg diff --git a/third_party/assets/simple/opacity_on_path.svg b/third_party/assets/simple/opacity_on_path.svg new file mode 100644 index 000000000000..9f870d066e21 --- /dev/null +++ b/third_party/assets/simple/opacity_on_path.svg @@ -0,0 +1,3 @@ + + + diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 9f71dbc39873..5aac8cee1c26 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -153,7 +153,7 @@ class DrawablePaint { } if (identical(a, DrawablePaint.empty) || identical(b, DrawablePaint.empty)) { - return a; + return a._withGroupOpacity(groupOpacity); } if (a == null) { From 4de6cce8f66e02da647b8e8d379581c2396020f4 Mon Sep 17 00:00:00 2001 From: Stefano Rodriguez Date: Fri, 7 Sep 2018 17:09:51 +0200 Subject: [PATCH 143/512] Fix NPE --- third_party/lib/src/vector_drawable.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 5aac8cee1c26..387e0e1fbaaf 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -153,7 +153,7 @@ class DrawablePaint { } if (identical(a, DrawablePaint.empty) || identical(b, DrawablePaint.empty)) { - return a._withGroupOpacity(groupOpacity); + return (a ?? b)._withGroupOpacity(groupOpacity); } if (a == null) { From 8fc63994809b9dcb21a32db433ef4c4c31fd5ef0 Mon Sep 17 00:00:00 2001 From: Stefano Rodriguez Date: Mon, 10 Sep 2018 18:20:24 +0200 Subject: [PATCH 144/512] Improve Gradients (#54) * Add support for gradientTransform. * PR changes. * Update deps * Fix linear gradients behaviour with decimal offsets * Fix linearGradient * Partial fix for radialGradient * Fix support for mockito 3.0 * Correctly apply transforms to the whole canvas rather than only to the path * Add NoopShader to handle unsupported shaders * Add linear and radial gradient svg assets with transforms * Improve gradient svg test assets * Add regenerated golden pngs * Make affineMatrix function public * Fix handling of gradientTransforms * Fix deprecation warning * Add support for percentage gradients with userSpaceOnUse --- ...gradient_absolute_user_space_translate.svg | 9 + ...gradient_percentage_bounding_translate.svg | 9 + ...adient_percentage_user_space_translate.svg | 9 + ...gradient_absolute_user_space_translate.svg | 9 + ...gradient_percentage_bounding_translate.svg | 9 + ...adient_percentage_user_space_translate.svg | 9 + third_party/golden/dart.png | Bin 4549 -> 4616 bytes third_party/golden/flutter_logo.png | Bin 2788 -> 2985 bytes ...gradient_absolute_user_space_translate.png | Bin 0 -> 5166 bytes ...gradient_percentage_bounding_translate.png | Bin 0 -> 2074 bytes ...adient_percentage_user_space_translate.png | Bin 0 -> 2144 bytes third_party/golden/simple/opacity_on_path.png | Bin 0 -> 1710 bytes ...gradient_absolute_user_space_translate.png | Bin 0 -> 16444 bytes .../golden/simple/radial_gradient_focal.png | Bin 12567 -> 12310 bytes ...gradient_percentage_bounding_translate.png | Bin 0 -> 8338 bytes ...adient_percentage_user_space_translate.png | Bin 0 -> 15730 bytes third_party/golden/w3samples/aa.png | Bin 6742 -> 6726 bytes .../golden/wikimedia/Ghostscript_Tiger.png | Bin 44393 -> 44529 bytes third_party/golden/wikimedia/chess_knight.png | Bin 6733 -> 6736 bytes third_party/lib/src/picture_provider.dart | 2 +- third_party/lib/src/svg/parsers.dart | 18 +- third_party/lib/src/svg/xml_parsers.dart | 175 +++++++++++++----- third_party/lib/src/svg_parser.dart | 29 ++- third_party/pubspec.lock | 120 ++++++------ third_party/pubspec.yaml | 4 +- third_party/test/widget_svg_test.dart | 12 +- 26 files changed, 285 insertions(+), 129 deletions(-) create mode 100644 third_party/assets/simple/linear_gradient_absolute_user_space_translate.svg create mode 100644 third_party/assets/simple/linear_gradient_percentage_bounding_translate.svg create mode 100644 third_party/assets/simple/linear_gradient_percentage_user_space_translate.svg create mode 100644 third_party/assets/simple/radial_gradient_absolute_user_space_translate.svg create mode 100644 third_party/assets/simple/radial_gradient_percentage_bounding_translate.svg create mode 100644 third_party/assets/simple/radial_gradient_percentage_user_space_translate.svg create mode 100644 third_party/golden/simple/linear_gradient_absolute_user_space_translate.png create mode 100644 third_party/golden/simple/linear_gradient_percentage_bounding_translate.png create mode 100644 third_party/golden/simple/linear_gradient_percentage_user_space_translate.png create mode 100644 third_party/golden/simple/opacity_on_path.png create mode 100644 third_party/golden/simple/radial_gradient_absolute_user_space_translate.png create mode 100644 third_party/golden/simple/radial_gradient_percentage_bounding_translate.png create mode 100644 third_party/golden/simple/radial_gradient_percentage_user_space_translate.png diff --git a/third_party/assets/simple/linear_gradient_absolute_user_space_translate.svg b/third_party/assets/simple/linear_gradient_absolute_user_space_translate.svg new file mode 100644 index 000000000000..ced5251b3e65 --- /dev/null +++ b/third_party/assets/simple/linear_gradient_absolute_user_space_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/assets/simple/linear_gradient_percentage_bounding_translate.svg b/third_party/assets/simple/linear_gradient_percentage_bounding_translate.svg new file mode 100644 index 000000000000..be1ef28c5502 --- /dev/null +++ b/third_party/assets/simple/linear_gradient_percentage_bounding_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/assets/simple/linear_gradient_percentage_user_space_translate.svg b/third_party/assets/simple/linear_gradient_percentage_user_space_translate.svg new file mode 100644 index 000000000000..c2b0ce07ffb1 --- /dev/null +++ b/third_party/assets/simple/linear_gradient_percentage_user_space_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/assets/simple/radial_gradient_absolute_user_space_translate.svg b/third_party/assets/simple/radial_gradient_absolute_user_space_translate.svg new file mode 100644 index 000000000000..4268fea810d2 --- /dev/null +++ b/third_party/assets/simple/radial_gradient_absolute_user_space_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/assets/simple/radial_gradient_percentage_bounding_translate.svg b/third_party/assets/simple/radial_gradient_percentage_bounding_translate.svg new file mode 100644 index 000000000000..3fd58495c8b6 --- /dev/null +++ b/third_party/assets/simple/radial_gradient_percentage_bounding_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/assets/simple/radial_gradient_percentage_user_space_translate.svg b/third_party/assets/simple/radial_gradient_percentage_user_space_translate.svg new file mode 100644 index 000000000000..303ff7d27ae3 --- /dev/null +++ b/third_party/assets/simple/radial_gradient_percentage_user_space_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/golden/dart.png b/third_party/golden/dart.png index 3526c7563521801bc6f98c80741f339d402e8e85..5793dfe6c124c536b36f261b2d0998a250be35d0 100644 GIT binary patch delta 4403 zcmV-35zOwzBZwrBL4UGIL_t(|obBCfP!!jK2k?Kx438i%f-(bwj=Y1rB$0;-dV?`O zZc;I(Ql+u9;$9`2WRtkrd`N1yc0cUat?XuRZRKHhQcEieg!)D?xO>5=2oHLvi3y8}LmpaO!8EaS*s;1?EQs%MyU~1|TIW6tyC9HRS;r zu>yO$fiJp%A*=G|eys=oCIiq2Q&%@4cT*OSVJooj8t}zc&%tn3k^uZ;E)dR;P>2LQ zAj4K*?=@i0)rr=_S0xF+KRpP91-@!Te_jPGAj4Lm`Wo=1pTThUXd>_rxeN(Sy?_TK zkil@qkWeTDEFeQxp!zEC<+X`BQo*olF7UV63<*sg&182lWSwX&syzh5-#)f`a*y7a z`0w9k`@c^jU-%u6+m?ye;tvYJ2*e3&--mNhj^3EK_4{TPLqfslb3g_y6D`Kxf9~J~ z!_z)R0AKe`{Qa%0ARKIpR8>`>v9ZyoZ6YHh5fc-G*w|R;bUGLe1|%mZ!)P?(fd?K4 zQcY(zp8~S~LO=HX(1klzAW8(nMZj#k`{(Z8gFUEXwuuOxf^czAfIs}*v?!^1dr>Xb{FPNzdrk>~S9RY2~HTk-y( zb6E9s5)cNA}EKwOV9mW@62nHF)*aSFwHjcIfqb+0XX% z^`WAo0;8j&Q(VjG&uc(FJz+x6z#Ra#v5;7 z{rdH?eU6(qZ({fEf88E0%Sg&&KrB`f?;iNk@!D*&$$l=OumFj9IY9}AGqwAlsUZ;r z0n3*!$IhKQk&uuedEaC*;k)m?3qj4MFOLD)eX<3YdIlY@$IQx;tdfcfpv%eh>EQmf zHr_sOzpFM=LjnNF$;o)_wbx|(90v~`#O>R+Lr|;fNiiUze+c~Z{(JGH0aR$?qJJ z$@EJ+g+R^wb~8C7g@uJUdh{sz`}-Yb7K;USb#+*|e{!YAZExMWg_@cgG&MEJcJ4<< zM=?4&ioU)+w6(RNzP=uUARs3v2dh@CQhm$%(@#IeojZ3Nul0I8o_XdO$7{3MjC1GC zp`oDxt*xz+x}>M4!(cEtUN<&2qN=LO>v7xL+wta`Z_2)>(P;4Y+i%MUW- zlVU(bQA9&S18Qn&e7-d-iXtvvyaEJ5+c7*m?09XlSR8+EZf?ex zUw(~f7VkFeQBXSJK2K2_>U8luFrI{c=2M% zt>3Fxue!7k3as1%F4=+g#(be#QMLMUi|OH z9>;5c=2|&#VOTOTlrPtk*!L}}m;>x@OXBXclN0rrNiB&+qd{tFDmpqkT*@zBzKnu` ze*%}Xs;VlqwzewnD=jSziHV7bkB>)0L8hXD3?_qXqu` zg_#qQ^z?K|K(1fE?(({!p#kU4os(=Ee-ROZl`B`GsHg~WadEQy9~>M+eSJNS9z6=H z)pa=F(4j-f%gb}=CwNm+Q{!@}1x(x&(ChU`OiaY=*|QNA7KWjrA<6tTgTa8+t5>^} z`8ruKENtT9$|WE_wB5uXzweOUKrN-*7?u=55JZ=|TheVk2PIIg2ml;9(*|JXe*`2o zHC0m9-QDf-`r(Hk#+55qP*+#yC^H(3*t~f&X3w7OasP2~ad`ak$B~hdfy&BC$>mv1 zO%2M+%T?9YeO_5)WF($?>M0Z#7pvM{uh&Zga{c;s*?_oz&Yepi(;G^jEsa{uSa=#xz}(wTexr`UU=aJ$2YK@ z$z;OKn>T%~cT!RkcJAD%Ivj!KXhB-K2l0pcwxA!-P+SDjYQ?Qf%EwZ=G$Q}S#KcI- z#>U2EKbxPQ?^tZ*&-g-GS{h19O7QKs-@24HH#cL>oH?rZqtof|$}6uRe>yta=Q;$6 zBj#`KJ0lq>SL&cE^*@v@uiVR%mn}tn=0de~qyUf`6!dhLYWD2eKD8X~7B5~bDQj!< z?F;z1=bj5`IDoqW>FysvRjqR0AQ%{usWm=6E-BM!CjHbWMX9N&lGexllFpNqloX_= zrw6)PKGOieM~BZV&a(=pf8=FL0l?$s76r!0$cUsYD$2J9UiA0(qqnyggM)*PyGLNJ&YN^gCi>W6{@lZ@}4kFwmPv9(ly4x&?~{06zat`M!6sF(gw%?&S0q5UbUS zix)5A%$YN2ZEf{zkEze>~Gkf79JRg4Ukfvi%AX zqHI4z6y^INBINraO67J8N$|;ynkObEDt^ATwH15z?7_gmfU5mlEEcr4x1+ti9mkI! zhhDGusl{*?A0O}cwt=LHjtJg$s4tvD!aG=jclq*VNtxWhoy}%LO-+sD4wSFl2O)js z>*ZgtXml|Vm_KJ0e>(frccA>?trY?8g=FB8^dFNZM{fE^N=k~$Yn#o6k3aqxEiK9u zOy|v;hpenDXti3{Y&HxI4x+!mA6;Et0bTPh1bca^N*Vwt%S(35QJO4ILGTt55rARY zQivjOt5q5jE~oa7eeHy^sHiApWMsIM)z;R^hC`##pscJ6e?>(_ino46QAAf)7tWqN zi_@o1yG&o7&NKk<;r0?7J$Dt?`lWX|lqmH>yl&_8ce#gC13+@g-ODYRkSNtf{#Z;D z031JlTvC>om*;ZV$!s>`@ZrOf&&9;V;H8&dQhZ{HogfHEOG`sqS{l}^TZj7kdK^4> zQ1rs8Co;zNXOl~oB5vWm1vi0gJ!Vo%)YsRCvuCBt7YYjt zU0$C*e_nQEecQHeUc=!|tJR{kwDcG8L`TP0$gdwxL*>hXo4gl@b1-FjDdH9`@OVPc zq?6rOq9|hT-o273)egxOMB6q-@cmMSdT6%OE?n^b!4OlkT2b-2SneU2Oe^B}oZBC7_@MF+ z4Y`kr06<+`olhO@fq?;3R8***o-&o>*2DDo_sjOZoOzvRVh_ot_m4ufSUeB(`8hVC zf0q3O*OxAbMySP&OOsn3e80JN?V4mAwlnA72N@h3L`O#lIy*Z(ZX*Z+Hf-2{Wy_X% zJochRi=fqNT_zNcjEvxe4?e)=&6_cQzVeq60Q~gRPx#`CFYenrSCNsCh>eYP888(^ z5!Kbz*tTt(;?#dt6S3?edHqk9kPtTUe_Mn~>?d)cgW~?}pIB0gh%n%)>0U^td+V`p z-@btEFFHCJ8#iuLbvG(1DhexBtiZ8j$6U($`ugzEM;~G7(xoUUC~!<`w}-T=s|zPi zoRG}D%E`$=Z*Q++ixvvm+1dF1`|n-Knwy*P-h1z1<;s=N>2w$x8bVJ`51N~sf3aoD z7WF^D_Dr!6<6;>8?dCYf!y>%Ss|r+5Je}CFOG{x41KKZkO#5&IT5fJGHg4P~yB1x^ z>eZ_qkMMD3wOUbITZ`J-T2=c=OiaX=U^)FB?N~M2MHQDKGskoDKa(t2umC%D?7;Tz+kFZL z0ECB!WBc~)lX|x9oH=t)US59R%*J)5*X!}*lTZ4zjn8x4UoMz~+#UipOlutjn zvuM#GY~H*%Xb+MOgcU0$rc@m|bV$_#F25FotTbrwTbqEl8pl;lV-FVRf4Z^4{v4|O{Ct=4l9Cdae??QFegK2riWMu6pP!GzhYzE%u~BxsCptPBTCEm>IEmln z`nnf*$7v?RR0Tz;!um+y^FoC;$#3@6f5ZNIX@R0ii&f^m^O1cdrucA+evpe}N3j4CqGCeJUUe z(%nM>$S;iYm9N2IkSNds_QVFckl0PdiOX=#VfJ6beCotm0%t!cb7C1^v0B_K^I`6n5N+0!0u- t(fbcs6A=*+5fKp)k=Rp_;1Czd_<#4ff&crx8O{Iz002ovPDHLkV1k(6q)q?; delta 4329 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 X^^;?sQN=%)00000NkvXXu0mjfR=SxB diff --git a/third_party/golden/flutter_logo.png b/third_party/golden/flutter_logo.png index 697659557c198659378f17bedc60115402cc9595..b02fbbf748009aca86896f25b4eda94ff30fb962 100644 GIT binary patch delta 2950 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 KwZh*2@_zw&9YF8^ literal 2788 zcmaJ@`#;m|8~remys4?gc z9&+9GTaZffyNp?$Cs(it4;lq1@4`>W9fb%A!xJe#7mzFn08o5}gPrHun_q^8PUF3F zTV}^(NneH@_4K<0lZsYRH47BO-E)g6BTDW~`kA(bAFB!bHBY$fdv*_cmN=LmH#N4~ zui&8w*PQjZcKe#fL4{KoW8-t0e+7RV6;)2s86nf}WnmJhy2`%czlSU%x~6ZAZ5koY z#*9UG$qb)+pN`V}L*uH%3Q#`dvnC*S;O;f+!RgG;kxtFo53tAp^Zyb}r`3&fR?oGi zeKeipHBPPtFDU4l%iHd|Cc$ zAtcOWIZe2Wj(CL|d?!dNOuc)o@$CMbI-YJaD03cti>BhE45P!9iRhmhyXrqd_Ksh@ z2xii>44nrU4R%|{txO~Yeja&u(u5DPMn5E)B!izvM@vi+LDtw*hlxBlHvf;RBR=%= z3QElZKlQoQ*fJR$?8whNhG9R=@_XQHE)BE%b>JpNBnjn|9}EylqE^a%>_rj|=V3!C zBussZ*yVs<5gi`4kj`wHa#({+h-GiXIpR4jx(p0^Q71a^79^a0YH5yD9-b=2vd!Xb ztsU_uiO*|@QvWaPdjmxDV~eSGe?jqQ5_c#`{e#Dr%dyHy;>lYi^kd%-Q|s9kwQ;W9~A!@4H zGw4k~Uk@zkQeanR zDb3`IVOHpl2E9jPD6}mS`RB6}9 zL25%ux?7Iebnn~LfCy@#O^s~#Fo(qGl&iU+uJnMQc`6GT0J5wftg z>#$0S6xt)7rwNU)D{|@}bnk;jDrt`)PWp5ge4+~3+FNpXgJPi^P|CM`)^-5zzD&^L zcVX$xA+6Y66`Yj01I|d(z`GC0!;47PtwITum^QffTa|{CX#?jmjQPbU)xk*parsk9 zrxJq6y0o_`KTeWGf}QY*v`t{afB-{_#?liwk+(-x`NcYCK8Zqf{Tc%J;4{e9y5^_E z&Iz3Vr#F0e#}V!)q#-!P3g0 zg-=7mET>d`BHWwgm3HkLY;>hT*^rld4_Pj_nj^+N~6lrrAwsTg%-zHj?6@QA!qg#@Fq-0X{!Pr!>`FLV}# z`UxqIxTpV}F;Yo%-}92x0{)bO$~r8a+_D zyReK3a><`uvL1clO!UTb=h9C7t`Ns^)Hb}7(ycZL2G?`vvNzNBl<@bS=kTk8ezan# zWHFY$A;;0f1>F2q{PSLT#=QX!b%D&07p4@Y6yiQK zR`&Tej@*ChC5?)fnRy=9OVA2GPOG%=6JVgxZi>f=!>w=pcBYEg46m5dssgUMA)Dd3 z+P3P{%WZ}~d^ZR%bkv07Z`7UqT?rEnQ`;k7N~kx%PZ zes+ZV)26vt8Y%S-jqMXU+Aw5*`G}8Rd$e|_FIz&b>`XcI)lzhoY(QP8ncS9P6t|b2| zQpxt|8Z@T1quW68K-+S0)|8zaUeVLHwT%~{yNb(t>p+zh(caOjw(u#6M@BM`E$baB zX1^U*bB5P)H4I$x#B?NC=$IfCl=A*$+Jz3^yJPS|Ve67vv*3Ij#VDSaF=mVlvQZis zEk9r{8}xg5Wm0_FKhbyQ>cV zJfmS4P4LRYBq72kC0bnVkVyKG1@x7s%AaoibK8seyNb(~2R6QskatKs^l0hjdeaMP zhYXB2H4xPu&u<~K|8^i; zBBjrfFcK`|85Tld88KLhgk@OI9(Kl0%I4H|&UVB8h`&DJUbAhdr%3F|!A7T`^=rY8 r^9hyNi;r!Ri*&hWTI&BHJ-=X-)-UHbdgN8hH&uW^b#W-C_+R=T?K<8} diff --git a/third_party/golden/simple/linear_gradient_absolute_user_space_translate.png b/third_party/golden/simple/linear_gradient_absolute_user_space_translate.png new file mode 100644 index 0000000000000000000000000000000000000000..369dd66e421d9ed2d31d5d8fc47ab29ff0a4ed71 GIT binary patch literal 5166 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 GKm0%b-2ANo literal 0 HcmV?d00001 diff --git a/third_party/golden/simple/linear_gradient_percentage_bounding_translate.png b/third_party/golden/simple/linear_gradient_percentage_bounding_translate.png new file mode 100644 index 0000000000000000000000000000000000000000..8d8489e0536758a7194b2707ab9e5c8848910a25 GIT binary patch literal 2074 zcmdUwk3UoUAIFCio3Ca@qK0iIb#M18g%;s7b8QKkl)CcUb*pc*R1`CdYm+V(;x1Zc zS6|7xH_0tm?rmelwXgKGi`3oHU8BSmn_>HY{2AZ#c%1V-@7H;~pXc>C=kYkFcz<}v zTFVWV2n1p+oknGV+OxVN&B3ubMtmIOlv~@UgvJ6HLL! zY~IMNI6{Ih#-3-Aw*a9gxl1X+qBseA`Q%zVA^{V7#0~AfKtn=ThD#*HyRfFeeaR&M z^d$vf{JAUIy_<$4C8l;OrS>Qe>CPo`Z4Hr74n;e1Z9_@Wl^S2wsU%(@jAf+Z!r$>R zG@^hfK>-FGu3(aH0tkPOfOeMxNK!zTvJgP1&t&AI_b|y%0EAOQK+9wRlHl2;)By)K5DNY}zH~m?5yi>QC;J?VCPB})sWwNf16d1r z^|`6Qu$E9dSqThY`Q$r?4w4|o4%NRS9D(6GUVYv*um*2J>0kc>&;3O{SDJPn=4#`Z2?u970 zm=G)nV==sr1>`WQ6Of|@%_+FeL6sbwOK8R`FP5bg{|pw#^2PDh;<%G~67pyzho)v? zP(JHU;<5aM%t#BO4a&!swc4=g5NL)g_N_K&>1#l9u;RVZMKo6R@Zo?FMN4iawH|5i zEBm3)jL#!EElPw(Gmnf|S7w8O!i)l?;?uh{#aGjFQPxx-k-mkZQfgzPCB;McWV7>nsYZXBjfJaPTA!Arl6jgv8ezwo8N-%5saSHG+j%Z)OIK7BsfE` zVqaYqJghiYc2?b|3?^YEF2ghH9~HqqFMy;SZq#@1NkxGorEqlVG)q4fj(2Zj9cM3B8#k2 z?{{eiC`qT*&Zp?+#7r;~yx`~R|4XK554(TH9!SaRe4N9djKz(rqCGs5~_}-a4q=;mLw8jl>@wSrq ziMtTvr*!qc!0{ORlx1+*@YCDj}Pqk)8?#~lhh7|TGto5m(#81oFPV; zWMzl{$^tAi+X-IF8%gJcb8bak3s6^bjen}%+Dkg$JsvG$YeJ70a>_@YriGg7kB@zw zYw1b4IeDafM$Mk?XCXy-+@+uu{mPS43)docS5BqxayRSc7f2CdRbRMKUs2y%zI}Nf z&7NMlJspJqPXC9~q?TLP*p}~T&=-M-C{bd^^nUj8e;zGgFI2|o3h#s9hfz|qRW;!F zREiI_C_Wn9d3LyO3MIAfm~J%anOKx0Lzr375+1-d+pH)8*BZU2?G&X)Okr6|Bx#! z6J$5BPu*cZG!AL#3%5bOE_Kc8u~FBh^qZ{~ob30>OVkWuUd<(t@=3^`QXVJNdh?Oe zoQ?ta4wgPnQbKbu{9VLea6T`824VB#)D?#D^Y@gu2VZWGbQ)$Ngx*GHqZwsEuyakl SVn6u5Bj~~5R52yt;{O1~@|x-Z literal 0 HcmV?d00001 diff --git a/third_party/golden/simple/linear_gradient_percentage_user_space_translate.png b/third_party/golden/simple/linear_gradient_percentage_user_space_translate.png new file mode 100644 index 0000000000000000000000000000000000000000..93891cbe084967bd5a4098cfd255d1fb83ee3a58 GIT binary patch literal 2144 zcmdUx{Xf(D8^<-D*c7&*vK+1L<0cg$jXGs^hD}l!ra2;Xj;)a#L`fg&*xYY!j)#~I z^F1Or(Q*^VP3}rj5{W4+mAT1X?m6qv_`V;H>$)D#>v}w{$Ln!jKU{C_IR{&1C5)1s zoSZV1LUxkHjvoeBkogjNsX!LC1v}Z2A%%tU=i_99U4(muyn^8jKG+IseuCoxUK-NO-t z9}3O=kPtYDs=;@SEp4Yf6Z&T5MGJN{3hiRQ3ZT#5xU(at}!4&{jJnot|)~~GTqt1T3@cm5vBwmAAFe%^o>ucA%_tM&o z7i$gi1T{@+?$&&`|7Qa<^wD)T^t6Z&q8Z%Tz}7LbdA~fcMS%nRI8|yteF&;YvD^6T z$t|)GW<!us6%kK$iAI;9kZx)D$Q zXc#2yG#~E$Bl*~H)RZfjPwS4F3*;l=X_GBQAA+ym__k;8VFFLE@wAKr2d_MHc+h4v z-x{ZOnBiMu(5yAP=;}?N5;t zg^qPTvm+Sp8Ps+rPM_&mqlPy2{!3sSr(g9Pk&ujDSn>ga$S#6 zRfIvz2o>`xcOP738~1CyxwgKTCD^QXd_UhEhd|#7TYEUV)vM%QtSj&~$}qNJMHTmf z`;px>$o9AH-*KAwlPiB8=Y5lR*52Db!tV+YN|q+peR2I*K}6NQgDYi>AdjVIZmfv8 zn6-ZJ0bTp}NzU6X0&Pn(8bx|BQF4T&MOpOz%m z_piT7b2nLCF8;0HXG@4i<^&~#EbTS1iCFNP<&|G_k%>#mnKJ7Y2dZz@*(2K*lYDa6 zu@)8q7)2+EY=W_<_Si1fiV*3@?pE1GlWGffCZ?Acb-g^hRI~VT+}lL0-eSL0`P2|q zjGfNO^H)G%G}H6&rK|S$!``JC+o)bBF`BekF690aA)mhI zHmTa2+Bw=1k>Jkxfj{O@5$)1`L5R)c|7>Vsiz zmW$`9h?-JGqj^RZ{h?iNnO^O?vS2Gg{^lU1ZBOJv|Bb%GumjWv!IvA!A|@)rcHqQx zxJhZjeykk<6~G!xW(kk z3xF{T1e{W4CB)g)_JLZn(=xhs6YscHZuq@uZh^(~O>iX$hNV)tZ<4Fn{)Oiwo4iZxgRt2@gD^$wlgdbZ7Gl%ziwzf45w(w=?r(qp{weTAq>SC@B%DAw^|$ z)9iN%X3PrLJJE=%s`>hk7-I_(3G0kYI)ds@?=g48=%Lv_Y;xAn{zSFJJmI9zJ6t)GjSpEqfd8 zrE87d!~|Yne?j`U;c=^f*LRZn8Gmts;CTX)OF2SlkmqrL;91KbPa46X!v zZ^xk!(>irT5ZBb(ypxPW+v^PdfShI(8PHK2GMLFBwsC+eY>Jcv5Re^b$k8mg+n>Ajus{9T^*rL(d>7!EeR4p|nIwwhh)0 zi~bG8Iml_D0;6bLkP1}&CncMNHN@Cfv~)Tj^W5f!;;JoAKe-%|PO)nX8xA2m6>Z4} Y?RXrTT<_)~`z6RxtsTgvB(LcI09(trE&u=k literal 0 HcmV?d00001 diff --git a/third_party/golden/simple/opacity_on_path.png b/third_party/golden/simple/opacity_on_path.png new file mode 100644 index 0000000000000000000000000000000000000000..3c73a53c114b3097929879b5a341c273cfbb70e4 GIT binary patch literal 1710 zcmd^Ai&N4E9A`xOOIKoY*HX_&PKL1UUa5t=eZFf2(sJtI$@6{V6zKTDIwZhysY-}`)D_xaxUzW2TF-M8#mWcX$q zM;izPvYCL#ku84c9|f!|wk=*Fu(+>s$l)On$%wPTlE8982+@E=SU_4S1Y#9W!2J+? zzIIW+7V(7XtXk&hcx#8@K5iA{JLgcY(7iz9g--_%xZHyqixAZf(TUI7dNX_8E3Mzu zRw{^ka59h?m;y^Eoc<-?)6&{{VP{q)7`3O`TxC)f23c=?7e}EysgoCS#UMI3U?=Pj+|dg^o=653}c;$i%@_1D~7TSuDj#aE@DR?ZFBiXS99I)5!4+YV)S zw4>xq4^kx2$!UIFFB{cr33YY4i5kqe$DY%o;cQILK&atUj$xRu$)eIojL-3!m!b&1 zP$1A`y)OlX6>^4~yfA5fQPPTEF_r|V$6ID_RZt(R>J;v^+MAm$s1wzg7_Ne4EDH$Dyz_vQF)X^5|KIm8WQl?JGf z0>UVSjZRsjdy&3C06W`J0R@gD=f>gC448;#dKGn^88b{2(XUa@eg~qb?eVCZnx@H> zk3o}@n>^rVd99l(l%W6IYXWHtySJpDJj?(+K?Dy#)260$(-%~NS-NE_JpK@XKIPyr zpNu7we3FYpEA8#^%}<{S#o`HyGpQaf0mE@fG2{JYE$l*9AFE7DoA2{2?P=I zQkl+wE0i#5%5`LxCs8P)0y_)Kz=E*(m|ZwoegZPruf7?wEMX* zP?Nq1?d#jY5w~`BHnfJgbH_Y=RD#>tu7~`f1ocSdqW5VZYY^$rOI$-n|85U((DU*V z#QYU3TbRZ?2*RpkJYx$gVLaa0hO)Px0koS|EA?n<1s;_LlX(oJy&{EU2_Dm|L7b(D zB$z}k;x>+P2KnK`65>?V)K?k!R_7~HyicS++Z@sf0wWCfS`e8WhFdP%iqHmHnowk zd3!9o$yqwlL2|%1yDFMAum3Eg=Rd;(=orhD8J?BL zyqk4k^>|AXOb28iFuc&Ne(W6@D#c(B%qvFA0d;gm_?;O8vp?3?(^Kn<;dqq#rD&?F zktLbs4-N|V#-$!zc7SGJXtbR?vw5Nt=H)eWk(G-9(M(rvSe2GIH@BQzwZ5*aJ2)Eq z+RVW!u3SbrIoYI5pNQ-^FZGs~9Po|9FO_|3{UP0rnQlfOp8E2J<^I#WK4bd%)b%<#(vFQ+WM4Tr)e{m#R)z z8ehG!Rc%+5$DMg@gMu%3@oleeEGbdu&w6_mWtAr<+bw6FDGuN7WTsK66O`P%BC2;8 uE9GkNTdG$3WBKEY{#x5_V9@^~zCb8-=)B6}F{0(?KnS6cI7vv#rN03r4!I=& literal 0 HcmV?d00001 diff --git a/third_party/golden/simple/radial_gradient_absolute_user_space_translate.png b/third_party/golden/simple/radial_gradient_absolute_user_space_translate.png new file mode 100644 index 0000000000000000000000000000000000000000..5c564d088e0b66bed4becb052b8742603821facd GIT binary patch literal 16444 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 literal 12567 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 W2Gdd=@m~Mj0MOMkyjP*&5cWUWbyHdZ diff --git a/third_party/golden/simple/radial_gradient_percentage_bounding_translate.png b/third_party/golden/simple/radial_gradient_percentage_bounding_translate.png new file mode 100644 index 0000000000000000000000000000000000000000..de39cf7f3c56c12518dfa51947eb0755ada9dcfb GIT binary patch literal 8338 zcmeHNXEYqZx8G>1x7CTVdheaE>aI@o5gP9WEmrz2NH~@eh0Mme&1{dwwVRJTwQb>)jZoP}1 zz4@q1m}&Y(Qn4u;o#0>n!Z~!*oHC=^($sA7nN$kH-LmYDXV)%L5T<030`}xVeEl@7 z^(Y?bCtnDtY!dmAXzH2m4?K4%k!Mj-O!WUh?f*a_hbsR$go^`5164C|+8~VP7=lnUNjBj&>=3M&y zI0I;y-Te(`W=oQfl+PwS<{J9t9dj5`*`N1RHqfk}F_N6eAuA_aTPY}=GV9Q$Yi8k4b6 z|2s&(vC#wWPw7VI9w$a@hX-I6FgjYFZGh0!$ir_V9I6p*>S8=%K(UX(-!%((P@=%h z^;4rX*=k2!2hlnaQ@#NhBv4i`tE|!aPr?s!Dt?!v0C8OV(@Y`t3?ua=D%S>m4Zvi% zz?q^WK;l7g2Zw&zGAXY%-#af~V7fE4d~rkE`&6ftakeaq3BbomEkJ*oE<{Q$zJMrwN;?;xloG^&%72 zYG^ltoTzZom}HjMo7FBYtT9y^KXAoO_;aj6c6(ha8HLINQiO`jkADzYB->J$RJw?f z`!~Zk>#-s@^}QG214Y|@@>Wl3*}Ew6YfJOiHBzkBlRtS-8rwcB?w1?lRt;#7JCm#3 z^Wl_P%J&=)nL6X8bF(C~C=B@K+8Pt(&mfNa9o1@UkTXeq+`i&r6t(vzlBKSS(aoVs zi(A)>7J>DkW)!k?*spqGIM<7{Ky``>i&4z#2#eLZFmf?%5PlqU0K8m2N^yYfi{rFqK zXvSg`qLUn)nBdw}#8--yqnKI@@R#Pu^>mOXws&5{Btoa~F1c4&{R~$_U z4}tg9sKhOWqvTXMj2GDWpcASqNw2n)&&z?U)=ie3;~Mefs_pg`nH*02MTl(PK$=;otPs z7>M0N#a1!#YF2Q#U|yq_iOb$)6gMlp)2*S1OFxYwc3-QDY9*^SL_5WD2xeRy8RA

-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 literal 0 HcmV?d00001 diff --git a/third_party/golden/simple/radial_gradient_percentage_user_space_translate.png b/third_party/golden/simple/radial_gradient_percentage_user_space_translate.png new file mode 100644 index 0000000000000000000000000000000000000000..6e23fcd2962b3879afe8f9b32b530e3b51cc5647 GIT binary patch literal 15730 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 BmB|1A literal 0 HcmV?d00001 diff --git a/third_party/golden/w3samples/aa.png b/third_party/golden/w3samples/aa.png index 9cc2f293b2c5a695ee3b63ae32a8640720d8be0d..e4a081b3ea2f38886fe11d9593077ad6b31ccb2d 100644 GIT binary patch delta 6585 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�SOnDMHzXW;~#c!U*dragzSb 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 Ua7*3kNnE(I) literal 6742 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 S>4Ci=JQYPv1+?7jp#K4J87eUV diff --git a/third_party/golden/wikimedia/Ghostscript_Tiger.png b/third_party/golden/wikimedia/Ghostscript_Tiger.png index 977f1ea17de3a4f7d53c40390e2c5592be3d4345..48f9512ca519d0a3c164f34b4f38ab96e1ceb6c0 100644 GIT binary patch literal 44529 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

lP{oi7W4 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 Y1JRpulGmS6E&u=k07*qoM6N<$f{rY(=Kufz diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index dbcb44ec2e81..29f987f2c989 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -481,7 +481,7 @@ class NetworkPicture extends PictureProvider { } final HttpClientResponse response = await request.close(); - if (response.statusCode != HttpStatus.OK) { + if (response.statusCode != HttpStatus.ok) { throw new HttpException('Could not get network asset', uri: uri); } final Uint8List bytes = await consolidateHttpClientResponseBytes(response); diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index 3b33101d96fd..6483493a06c0 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -116,17 +116,17 @@ Matrix4 _parseSvgMatrix(String paramsStr, Matrix4 current) { final double e = double.parse(params[4]); final double f = double.parse(params[5]); - return _affineMatrix(a, b, c, d, e, f).multiplied(current); + return affineMatrix(a, b, c, d, e, f).multiplied(current); } Matrix4 _parseSvgSkewX(String paramsStr, Matrix4 current) { final double x = double.parse(paramsStr); - return _affineMatrix(1.0, 0.0, tan(x), 1.0, 0.0, 0.0).multiplied(current); + return affineMatrix(1.0, 0.0, tan(x), 1.0, 0.0, 0.0).multiplied(current); } Matrix4 _parseSvgSkewY(String paramsStr, Matrix4 current) { final double y = double.parse(paramsStr); - return _affineMatrix(1.0, tan(y), 0.0, 1.0, 0.0, 0.0).multiplied(current); + return affineMatrix(1.0, tan(y), 0.0, 1.0, 0.0, 0.0).multiplied(current); } Matrix4 _parseSvgTranslate(String paramsStr, Matrix4 current) { @@ -135,7 +135,7 @@ Matrix4 _parseSvgTranslate(String paramsStr, Matrix4 current) { assert(params.length <= 2); final double x = double.parse(params[0]); final double y = params.length < 2 ? x : double.parse(params[1]); - return _affineMatrix(1.0, 0.0, 0.0, 1.0, x, y).multiplied(current); + return affineMatrix(1.0, 0.0, 0.0, 1.0, x, y).multiplied(current); } Matrix4 _parseSvgScale(String paramsStr, Matrix4 current) { @@ -144,7 +144,7 @@ Matrix4 _parseSvgScale(String paramsStr, Matrix4 current) { assert(params.length <= 2); final double x = double.parse(params[0]); final double y = params.length < 2 ? x : double.parse(params[1]); - return _affineMatrix(x, 0.0, 0.0, y, 0.0, 0.0).multiplied(current); + return affineMatrix(x, 0.0, 0.0, y, 0.0, 0.0).multiplied(current); } Matrix4 _parseSvgRotate(String paramsStr, Matrix4 current) { @@ -153,21 +153,21 @@ Matrix4 _parseSvgRotate(String paramsStr, Matrix4 current) { final double a = radians(double.parse(params[0])); final Matrix4 rotate = - _affineMatrix(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0); + affineMatrix(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0); if (params.length > 1) { final double x = double.parse(params[1]); final double y = params.length == 3 ? double.parse(params[2]) : x; - return _affineMatrix(1.0, 0.0, 0.0, 1.0, x, y) + return affineMatrix(1.0, 0.0, 0.0, 1.0, x, y) .multiplied(current) .multiplied(rotate) - .multiplied(_affineMatrix(1.0, 0.0, 0.0, 1.0, -x, -y)); + .multiplied(affineMatrix(1.0, 0.0, 0.0, 1.0, -x, -y)); } else { return rotate.multiplied(current); } } -Matrix4 _affineMatrix( +Matrix4 affineMatrix( double a, double b, double c, double d, double e, double f) { return new Matrix4( a, b, 0.0, 0.0, c, d, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, e, f, 0.0, 1.0); diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index b213091cf963..fcf8298fdb4d 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -55,15 +55,15 @@ Rect parseViewBox(XmlElement svg) { String buildUrlIri(XmlElement def) => 'url(#${getAttribute(def, 'id')})'; -/// Parses a element, extracting and (TODO) elements into the `paintServers` map. +/// Parses a element, extracting and elements into the `paintServers` map. /// /// Returns any elements it was not able to process. Iterable parseDefs( - XmlElement el, DrawableDefinitionServer definitions) sync* { + XmlElement el, DrawableDefinitionServer definitions, Rect rootBounds) sync* { for (XmlNode def in el.children) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { - definitions.addPaintServer(buildUrlIri(def), parseGradient(def)); + definitions.addPaintServer(buildUrlIri(def), parseGradient(def, rootBounds)); } else if (def.name.local == 'clipPath') { definitions.addClipPath(buildUrlIri(def), parseClipPathDefinition(def)); } else { @@ -74,13 +74,19 @@ Iterable parseDefs( } double _parseDecimalOrPercentage(String val, {double multiplier = 1.0}) { - if (val.endsWith('%')) { - return double.parse(val.substring(0, val.length - 1)) / 100 * multiplier; + if (_isPercentage(val)) { + return _parsePercentage(val, multiplier: multiplier); } else { return double.parse(val); } } +double _parsePercentage(String val, {double multiplier = 1.0}) { + return double.parse(val.substring(0, val.length - 1)) / 100 * multiplier; +} + +bool _isPercentage(String val) => val.endsWith('%'); + TileMode parseTileMode(XmlElement el) { final String spreadMethod = getAttribute(el, 'spreadMethod', def: 'pad'); switch (spreadMethod) { @@ -102,21 +108,20 @@ void parseStops( colors[i] = parseColor(getAttribute(stops[i], 'stop-color')) .withOpacity(double.parse(rawOpacity)); - final String rawOffset = getAttribute(stops[i], 'offset'); + final String rawOffset = getAttribute(stops[i], 'offset', def: '0%'); offsets[i] = _parseDecimalOrPercentage(rawOffset); } } /// Parses an SVG element into a [Paint]. -PaintServer parseLinearGradient(XmlElement el) { - final double x1 = - _parseDecimalOrPercentage(getAttribute(el, 'x1', def: '0%')); - final double x2 = - _parseDecimalOrPercentage(getAttribute(el, 'x2', def: '100%')); - final double y1 = - _parseDecimalOrPercentage(getAttribute(el, 'y1', def: '0%')); - final double y2 = - _parseDecimalOrPercentage(getAttribute(el, 'y2', def: '0%')); +PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { + final String gradientUnits = getAttribute(el, 'gradientUnits', def: 'objectBoundingBox'); + final bool isObjectBoundingBox = gradientUnits == 'objectBoundingBox'; + + final String x1 = getAttribute(el, 'x1', def: '0%'); + final String x2 = getAttribute(el, 'x2', def: '100%'); + final String y1 = getAttribute(el, 'y1', def: '0%'); + final String y2 = getAttribute(el, 'y2', def: '0%'); final TileMode spreadMethod = parseTileMode(el); final List stops = el.findElements('stop').toList(); @@ -125,19 +130,68 @@ PaintServer parseLinearGradient(XmlElement el) { parseStops(stops, colors, offsets); + final Matrix4 originalTransform = parseTransform(getAttribute(el, 'gradientTransform', def: null)); + return (Rect bounds) { - final Offset from = new Offset( - bounds.left + (bounds.width * x1), - bounds.left + (bounds.height * y1), - ); - final Offset to = new Offset( - bounds.left + (bounds.width * x2), - bounds.left + (bounds.height * y2), - ); + Vector3 from, to; + Matrix4 transform = originalTransform?.clone() ?? new Matrix4.identity(); + + if (isObjectBoundingBox) { + final Matrix4 scale = affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); + final Matrix4 translate = affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); + transform = translate.multiplied(scale)..multiply(transform); + + final Offset fromOffset = new Offset( + _parseDecimalOrPercentage(x1), + _parseDecimalOrPercentage(y1), + ); + final Offset toOffset = new Offset( + _parseDecimalOrPercentage(x2), + _parseDecimalOrPercentage(y2), + ); + + from = new Vector3( + fromOffset.dx, + fromOffset.dy, + 0.0, + ); + to = new Vector3( + toOffset.dx, + toOffset.dy, + 0.0, + ); + } else { + final Offset fromOffset = new Offset( + _isPercentage(x1) + ? _parsePercentage(x1) * rootBounds.width + rootBounds.left + : double.parse(x1), + _isPercentage(y1) + ? _parsePercentage(y1) * rootBounds.height + rootBounds.top + : double.parse(y1), + ); + + + final Offset toOffset = new Offset( + _isPercentage(x2) + ? _parsePercentage(x2) * rootBounds.width + rootBounds.left + : double.parse(x2), + _isPercentage(y2) + ? _parsePercentage(y2) * rootBounds.height + rootBounds.top + : double.parse(y2), + ); + + from = new Vector3(fromOffset.dx, fromOffset.dy, 0.0); + to = new Vector3(toOffset.dx, toOffset.dy, 0.0); + } + + if (transform != null) { + from = transform.transform3(from); + to = transform.transform3(to); + } return new Gradient.linear( - from, - to, + new Offset(from.x, from.y), + new Offset(to.x, to.y), colors, offsets, spreadMethod, @@ -146,9 +200,15 @@ PaintServer parseLinearGradient(XmlElement el) { } /// Parses a into a [Paint]. -PaintServer parseRadialGradient(XmlElement el) { +PaintServer parseRadialGradient(XmlElement el, Rect rootBounds) { + final String gradientUnits = getAttribute(el, 'gradientUnits', def: 'objectBoundingBox'); + final bool isObjectBoundingBox = gradientUnits == 'objectBoundingBox'; + final String rawCx = getAttribute(el, 'cx', def: '50%'); final String rawCy = getAttribute(el, 'cy', def: '50%'); + final String rawR = getAttribute(el, 'r', def: '50%'); + final String rawFx = getAttribute(el, 'fx', def: rawCx); + final String rawFy = getAttribute(el, 'fy', def: rawCy); final TileMode spreadMethod = parseTileMode(el); final List stops = el.findElements('stop').toList(); @@ -157,27 +217,39 @@ PaintServer parseRadialGradient(XmlElement el) { final List offsets = new List(stops.length); parseStops(stops, colors, offsets); + final Matrix4 originalTransform = parseTransform(getAttribute(el, 'gradientTransform', def: null)); + return (Rect bounds) { - final double cx = _parseDecimalOrPercentage( - rawCx, - multiplier: bounds.width + bounds.left + bounds.left, - ); - final double cy = _parseDecimalOrPercentage( - rawCy, - multiplier: bounds.height + bounds.top + bounds.top, - ); - final double r = _parseDecimalOrPercentage( - getAttribute(el, 'r', def: '50%'), - multiplier: (bounds.width + bounds.height) / 2, - ); - final double fx = _parseDecimalOrPercentage( - getAttribute(el, 'fx', def: rawCx), - multiplier: bounds.width + (bounds.left * 2), - ); - final double fy = _parseDecimalOrPercentage( - getAttribute(el, 'fy', def: rawCy), - multiplier: bounds.height + (bounds.top), - ); + double cx, cy, r, fx, fy; + Matrix4 transform = originalTransform?.clone() ?? new Matrix4.identity(); + + if (isObjectBoundingBox) { + final Matrix4 scale = affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); + final Matrix4 translate = affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); + transform = translate.multiplied(scale)..multiply(transform); + + cx = _parseDecimalOrPercentage(rawCx); + cy = _parseDecimalOrPercentage(rawCy); + r = _parseDecimalOrPercentage(rawR); + fx = _parseDecimalOrPercentage(rawFx); + fy = _parseDecimalOrPercentage(rawFy); + } else { + cx = _isPercentage(rawCx) + ? _parsePercentage(rawCx) * rootBounds.width + rootBounds.left + : double.parse(rawCx); + cy = _isPercentage(rawCy) + ? _parsePercentage(rawCy) * rootBounds.height + rootBounds.top + : double.parse(rawCy); + r = _isPercentage(rawR) + ? _parsePercentage(rawR) * ((rootBounds.height + rootBounds.width) / 2) + : double.parse(rawR); + fx = _isPercentage(rawFx) + ? _parsePercentage(rawFx) * rootBounds.width + rootBounds.left + : double.parse(rawFx); + fy = _isPercentage(rawFy) + ? _parsePercentage(rawFy) * rootBounds.height + rootBounds.top + : double.parse(rawFy); + } final Offset center = new Offset(cx, cy); final Offset focal = @@ -189,7 +261,7 @@ PaintServer parseRadialGradient(XmlElement el) { colors, offsets, spreadMethod, - null, + transform?.storage, focal, 0.0, ); @@ -233,11 +305,11 @@ List parseClipPath(XmlElement el, DrawableDefinitionServer definitions) { } /// Parses a or into a [Paint]. -PaintServer parseGradient(XmlElement el) { +PaintServer parseGradient(XmlElement el, Rect rootBounds) { if (el.name.local == 'linearGradient') { - return parseLinearGradient(el); + return parseLinearGradient(el, rootBounds); } else if (el.name.local == 'radialGradient') { - return parseRadialGradient(el); + return parseRadialGradient(el, rootBounds); } throw new StateError('Unknown gradient type ${el.name.local}'); } @@ -287,7 +359,7 @@ double parseOpacity(XmlElement el) { DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri, DrawableDefinitionServer definitions, Rect bounds, {double opacity}) { - final Shader shader = definitions.getPaint(iri, bounds); + Shader shader = definitions.getPaint(iri, bounds); if (shader == null) { FlutterError.onError( new FlutterErrorDetails( @@ -305,6 +377,7 @@ DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri, ), ); } + return new DrawablePaint( paintingStyle, shader: shader, diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index bc486fc89aae..bdf105a3b6a9 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -12,7 +12,9 @@ import 'vector_drawable.dart'; /// An SVG Shape element that will be drawn to the canvas. class DrawableSvgShape extends DrawableShape { - const DrawableSvgShape(Path path, DrawableStyle style) : super(path, style); + const DrawableSvgShape(Path path, DrawableStyle style, this.transform) : super(path, style); + + final Matrix4 transform; /// Applies the transformation in the @transform attribute to the path. factory DrawableSvgShape.parse( @@ -35,35 +37,48 @@ class DrawableSvgShape extends DrawableShape { final Path path = pathFactory(el); return new DrawableSvgShape( - applyTransformIfNeeded(path, el), + path, parseStyle(el, definitions, path.getBounds(), parentStyle, defaultFillIfNotSpecified: defaultFill, defaultStrokeIfNotSpecified: defaultStroke), + parseTransform(getAttribute(el, 'transform', def: null)), ); } + + @override + void draw(Canvas canvas, ColorFilter colorFilter) { + if (transform != null) { + canvas.save(); + canvas.transform(transform.storage); + super.draw(canvas, colorFilter); + canvas.restore(); + } else { + super.draw(canvas, colorFilter); + } + } } /// Creates a [Drawable] from an SVG or shape element. Also handles parsing and gradients. /// /// If an unsupported element is encountered, it will be created as a [DrawableNoop]. Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, - Rect bounds, DrawableStyle parentStyle, String key) { + Rect rootBounds, DrawableStyle parentStyle, String key) { final Function unhandled = (XmlElement e) => _unhandledElement(e, key); final SvgPathFactory shapeFn = svgPathParsers[el.name.local]; if (shapeFn != null) { return new DrawableSvgShape.parse(shapeFn, definitions, el, parentStyle); } else if (el.name.local == 'defs') { - parseDefs(el, definitions).forEach(unhandled); + parseDefs(el, definitions, rootBounds).forEach(unhandled); return new DrawableNoop(el.name.local); } else if (el.name.local.endsWith('Gradient')) { definitions.addPaintServer( - 'url(#${getAttribute(el, 'id')})', parseGradient(el)); + 'url(#${getAttribute(el, 'id')})', parseGradient(el, rootBounds)); return new DrawableNoop(el.name.local); } else if (el.name.local == 'g' || el.name.local == 'a') { - return parseSvgGroup(el, definitions, bounds, parentStyle, key); + return parseSvgGroup(el, definitions, rootBounds, parentStyle, key); } else if (el.name.local == 'text') { - return parseSvgText(el, definitions, bounds, parentStyle); + return parseSvgText(el, definitions, rootBounds, parentStyle); } else if (el.name.local == 'svg') { throw new UnsupportedError( 'Nested SVGs not supported in this implementation.'); diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index cff085483115..a9a447538aae 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -7,63 +7,63 @@ packages: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.31.2-alpha.2" + version: "0.32.4" args: dependency: transitive description: name: args url: "https://pub.dartlang.org" source: hosted - version: "1.4.3" + version: "1.5.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.0.7" + version: "2.0.8" boolean_selector: dependency: transitive description: name: boolean_selector url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.4" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.1.1" + version: "1.1.2" collection: dependency: transitive description: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.6" + version: "1.14.11" convert: dependency: transitive description: name: convert url: "https://pub.dartlang.org" source: hosted - version: "2.0.1" + version: "2.0.2" crypto: dependency: transitive description: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "2.0.6" csslib: dependency: transitive description: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.14.4" + version: "0.14.5" flutter: dependency: "direct main" description: flutter @@ -80,133 +80,140 @@ packages: name: front_end url: "https://pub.dartlang.org" source: hosted - version: "0.1.0-alpha.12" + version: "0.1.4" glob: dependency: transitive description: name: glob url: "https://pub.dartlang.org" source: hosted - version: "1.1.5" + version: "1.1.7" html: dependency: transitive description: name: html url: "https://pub.dartlang.org" source: hosted - version: "0.13.3" + version: "0.13.3+3" http: dependency: transitive description: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.11.3+16" + version: "0.11.3+17" http_multi_server: dependency: transitive description: name: http_multi_server url: "https://pub.dartlang.org" source: hosted - version: "2.0.4" + version: "2.0.5" http_parser: dependency: transitive description: name: http_parser url: "https://pub.dartlang.org" source: hosted - version: "3.1.2" + version: "3.1.3" io: dependency: transitive description: name: io url: "https://pub.dartlang.org" source: hosted - version: "0.3.2+1" + version: "0.3.3" js: dependency: transitive description: name: js url: "https://pub.dartlang.org" source: hosted - version: "0.6.1" + version: "0.6.1+1" + json_rpc_2: + dependency: transitive + description: + name: json_rpc_2 + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.9" kernel: dependency: transitive description: name: kernel url: "https://pub.dartlang.org" source: hosted - version: "0.3.0-alpha.12" + version: "0.3.4" logging: dependency: transitive description: name: logging url: "https://pub.dartlang.org" source: hosted - version: "0.11.3+1" + version: "0.11.3+2" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.2+1" + version: "0.12.3+1" meta: dependency: "direct main" description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.5" + version: "1.1.6" mime: dependency: transitive description: name: mime url: "https://pub.dartlang.org" source: hosted - version: "0.9.6" + version: "0.9.6+2" mockito: dependency: "direct dev" description: name: mockito url: "https://pub.dartlang.org" source: hosted - version: "2.2.3" + version: "3.0.0" multi_server_socket: dependency: transitive description: name: multi_server_socket url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.0.2" node_preamble: dependency: transitive description: name: node_preamble url: "https://pub.dartlang.org" source: hosted - version: "1.4.1" + version: "1.4.4" package_config: dependency: transitive description: name: package_config url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.5" package_resolver: dependency: transitive description: name: package_resolver url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.0.4" path: dependency: "direct dev" description: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.5.1" + version: "1.6.2" path_drawing: dependency: "direct main" description: @@ -227,63 +234,63 @@ packages: name: petitparser url: "https://pub.dartlang.org" source: hosted - version: "1.7.7" + version: "2.0.0" plugin: dependency: transitive description: name: plugin url: "https://pub.dartlang.org" source: hosted - version: "0.2.0+2" + version: "0.2.0+3" pool: dependency: transitive description: name: pool url: "https://pub.dartlang.org" source: hosted - version: "1.3.4" + version: "1.3.6" pub_semver: dependency: transitive description: name: pub_semver url: "https://pub.dartlang.org" source: hosted - version: "1.4.1" + version: "1.4.2" quiver: dependency: transitive description: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "0.29.0+1" + version: "2.0.0+1" shelf: dependency: transitive description: name: shelf url: "https://pub.dartlang.org" source: hosted - version: "0.7.3" + version: "0.7.3+3" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler url: "https://pub.dartlang.org" source: hosted - version: "1.0.3" + version: "1.0.4" shelf_static: dependency: transitive description: name: shelf_static url: "https://pub.dartlang.org" source: hosted - version: "0.2.7" + version: "0.2.8" shelf_web_socket: dependency: transitive description: name: shelf_web_socket url: "https://pub.dartlang.org" source: hosted - version: "0.2.2" + version: "0.2.2+4" sky_engine: dependency: transitive description: flutter @@ -295,105 +302,112 @@ packages: name: source_map_stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.1.4" + version: "1.1.5" source_maps: dependency: transitive description: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.5" + version: "0.10.7" source_span: dependency: transitive description: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.4.0" + version: "1.4.1" stack_trace: dependency: transitive description: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.2" + version: "1.9.3" stream_channel: dependency: transitive description: name: stream_channel url: "https://pub.dartlang.org" source: hosted - version: "1.6.6" + version: "1.6.8" string_scanner: dependency: transitive description: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.0.2" + version: "1.0.4" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.0.0" + version: "1.0.1" test: dependency: "direct dev" description: name: test url: "https://pub.dartlang.org" source: hosted - version: "0.12.37" + version: "1.3.0" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.5" + version: "1.1.6" utf: dependency: transitive description: name: utf url: "https://pub.dartlang.org" source: hosted - version: "0.9.0+4" + version: "0.9.0+5" vector_math: dependency: "direct main" description: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.6" + version: "2.0.8" + vm_service_client: + dependency: transitive + description: + name: vm_service_client + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.6" watcher: dependency: transitive description: name: watcher url: "https://pub.dartlang.org" source: hosted - version: "0.9.7+7" + version: "0.9.7+10" web_socket_channel: dependency: transitive description: name: web_socket_channel url: "https://pub.dartlang.org" source: hosted - version: "1.0.7" + version: "1.0.9" xml: dependency: "direct main" description: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.0.0" + version: "3.2.0" yaml: dependency: transitive description: name: yaml url: "https://pub.dartlang.org" source: hosted - version: "2.1.13" + version: "2.1.15" sdks: - dart: ">=2.0.0-dev.52.0 <=2.0.0-dev.58.0.flutter-f981f09760" + dart: ">=2.0.0-dev.69.0 <3.0.0" flutter: ">=0.5.1 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 8d9f070d0f70..8c468d30f71f 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -13,9 +13,9 @@ dependencies: sdk: flutter dev_dependencies: - mockito: ^2.2.3 + mockito: ^3.0.0 path: ^1.5.1 - test: ^0.12.37 + test: ^1.3.0 flutter_test: sdk: flutter diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index ccedb5428fb4..cf07112543ea 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -140,18 +140,18 @@ void main() { final MockHttpClientRequest mockRequest = new MockHttpClientRequest(); final MockHttpClientResponse mockResponse = new MockHttpClientResponse(); - when(mockHttpClient.getUrl(typed(any))) + when(mockHttpClient.getUrl(any)) .thenAnswer((_) => new Future.value(mockRequest)); when(mockRequest.close()).thenAnswer( (_) => new Future.value(mockResponse)); - when(mockResponse.transform(typed(any))) + when(mockResponse.transform(any)) .thenAnswer((_) => new Stream.fromIterable([svg])); - when(mockResponse.listen(typed(any), - onDone: typed(any, named: 'onDone'), - onError: typed(any, named: 'onError'), - cancelOnError: typed(any, named: 'cancelOnError'))) + when(mockResponse.listen(any, + onDone: anyNamed('onDone'), + onError: anyNamed('onError'), + cancelOnError: anyNamed('cancelOnError'))) .thenAnswer((Invocation invocation) { final void Function(Uint8List) onData = invocation.positionalArguments[0]; final void Function(Object) onError = invocation.namedArguments[#onError]; From 9f13160931a6dcf4d03ea7696fa5038897edc859 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Sep 2018 20:02:36 -0700 Subject: [PATCH 145/512] move stuff around --- third_party/android/.gitignore | 10 - third_party/android/.project | 17 - .../org.eclipse.buildship.core.prefs | 2 - third_party/android/app/.classpath | 6 - third_party/android/app/.project | 23 - .../org.eclipse.buildship.core.prefs | 2 - third_party/android/app/build.gradle | 51 -- .../android/app/src/main/AndroidManifest.xml | 39 - .../com/example/fluttersvg/MainActivity.java | 14 - .../main/res/drawable/launch_background.xml | 12 - .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 544 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 442 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 721 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 1031 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 1443 -> 0 bytes .../app/src/main/res/values/styles.xml | 8 - third_party/android/build.gradle | 29 - third_party/android/gradle.properties | 1 - .../android/gradle/wrapper/gradle-wrapper.jar | Bin 53636 -> 0 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 - third_party/android/gradlew | 160 ---- third_party/android/gradlew.bat | 90 --- third_party/android/settings.gradle | 15 - .../assets/android_vd/battery_charging.xml | 22 - third_party/assets/dart.svg | 50 -- .../deborah_ufw/new-action-expander.svg | 14 - third_party/assets/deborah_ufw/new-camera.svg | 21 - .../assets/deborah_ufw/new-gif-button.svg | 32 - third_party/assets/deborah_ufw/new-gif.svg | 30 - third_party/assets/deborah_ufw/new-image.svg | 19 - .../assets/deborah_ufw/new-mention.svg | 22 - .../assets/deborah_ufw/new-pause-button.svg | 22 - .../assets/deborah_ufw/new-play-button.svg | 16 - .../assets/deborah_ufw/new-send-circle.svg | 27 - third_party/assets/deborah_ufw/numeric_25.svg | 19 - third_party/assets/flutter_logo.svg | 20 - third_party/assets/simple/clip_path.svg | 13 - third_party/assets/simple/clip_path_2.svg | 9 - third_party/assets/simple/clip_path_3.svg | 13 - third_party/assets/simple/dash_path.svg | 14 - third_party/assets/simple/ellipse.svg | 5 - .../assets/simple/group_fill_opacity.svg | 28 - third_party/assets/simple/group_opacity.svg | 46 -- third_party/assets/simple/linear_gradient.svg | 11 - .../assets/simple/linear_gradient_2.svg | 24 - ...gradient_absolute_user_space_translate.svg | 9 - ...gradient_percentage_bounding_translate.svg | 9 - ...adient_percentage_user_space_translate.svg | 9 - third_party/assets/simple/nested_group.svg | 8 - third_party/assets/simple/opacity_on_path.svg | 3 - third_party/assets/simple/radial_gradient.svg | 26 - ...gradient_absolute_user_space_translate.svg | 9 - .../assets/simple/radial_gradient_focal.svg | 13 - ...gradient_percentage_bounding_translate.svg | 9 - ...adient_percentage_user_space_translate.svg | 9 - third_party/assets/simple/rect_rrect.svg | 6 - .../assets/simple/rect_rrect_no_ry.svg | 3 - third_party/assets/simple/style_attr.svg | 6 - third_party/assets/simple/text.svg | 16 - third_party/assets/w3samples/aa.svg | 5 - third_party/assets/w3samples/alphachannel.svg | 5 - .../assets/wikimedia/Ghostscript_Tiger.svg | 725 ------------------ third_party/assets/wikimedia/chess_knight.svg | 23 - third_party/example/main.dart | 168 ---- third_party/ios/.gitignore | 42 - .../ios/Flutter/AppFrameworkInfo.plist | 30 - third_party/ios/Flutter/Debug.xcconfig | 1 - third_party/ios/Flutter/Release.xcconfig | 1 - .../ios/Runner.xcodeproj/project.pbxproj | 436 ----------- .../contents.xcworkspacedata | 7 - .../xcshareddata/xcschemes/Runner.xcscheme | 93 --- .../contents.xcworkspacedata | 7 - third_party/ios/Runner/AppDelegate.h | 6 - third_party/ios/Runner/AppDelegate.m | 12 - .../AppIcon.appiconset/Contents.json | 122 --- .../Icon-App-1024x1024@1x.png | Bin 11112 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 564 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 1588 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 1025 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 1716 -> 0 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 1920 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 1283 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 1895 -> 0 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 2665 -> 0 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 3831 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 1888 -> 0 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 3294 -> 0 bytes .../Icon-App-83.5x83.5@2x.png | Bin 3612 -> 0 bytes .../LaunchImage.imageset/Contents.json | 23 - .../LaunchImage.imageset/LaunchImage.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/README.md | 5 - .../Runner/Base.lproj/LaunchScreen.storyboard | 37 - .../ios/Runner/Base.lproj/Main.storyboard | 26 - third_party/ios/Runner/Info.plist | 49 -- third_party/ios/Runner/main.m | 9 - third_party/pubspec.lock | 2 +- third_party/pubspec.yaml | 23 +- third_party/test/golden_svg_test.dart | 4 +- third_party/tool/gen_golden.dart | 6 +- 103 files changed, 7 insertions(+), 2957 deletions(-) delete mode 100644 third_party/android/.gitignore delete mode 100644 third_party/android/.project delete mode 100644 third_party/android/.settings/org.eclipse.buildship.core.prefs delete mode 100644 third_party/android/app/.classpath delete mode 100644 third_party/android/app/.project delete mode 100644 third_party/android/app/.settings/org.eclipse.buildship.core.prefs delete mode 100644 third_party/android/app/build.gradle delete mode 100644 third_party/android/app/src/main/AndroidManifest.xml delete mode 100644 third_party/android/app/src/main/java/com/example/fluttersvg/MainActivity.java delete mode 100644 third_party/android/app/src/main/res/drawable/launch_background.xml delete mode 100644 third_party/android/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 third_party/android/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 third_party/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 third_party/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 third_party/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 third_party/android/app/src/main/res/values/styles.xml delete mode 100644 third_party/android/build.gradle delete mode 100644 third_party/android/gradle.properties delete mode 100644 third_party/android/gradle/wrapper/gradle-wrapper.jar delete mode 100644 third_party/android/gradle/wrapper/gradle-wrapper.properties delete mode 100755 third_party/android/gradlew delete mode 100644 third_party/android/gradlew.bat delete mode 100644 third_party/android/settings.gradle delete mode 100644 third_party/assets/android_vd/battery_charging.xml delete mode 100644 third_party/assets/dart.svg delete mode 100644 third_party/assets/deborah_ufw/new-action-expander.svg delete mode 100644 third_party/assets/deborah_ufw/new-camera.svg delete mode 100644 third_party/assets/deborah_ufw/new-gif-button.svg delete mode 100644 third_party/assets/deborah_ufw/new-gif.svg delete mode 100644 third_party/assets/deborah_ufw/new-image.svg delete mode 100644 third_party/assets/deborah_ufw/new-mention.svg delete mode 100644 third_party/assets/deborah_ufw/new-pause-button.svg delete mode 100644 third_party/assets/deborah_ufw/new-play-button.svg delete mode 100644 third_party/assets/deborah_ufw/new-send-circle.svg delete mode 100644 third_party/assets/deborah_ufw/numeric_25.svg delete mode 100644 third_party/assets/flutter_logo.svg delete mode 100644 third_party/assets/simple/clip_path.svg delete mode 100644 third_party/assets/simple/clip_path_2.svg delete mode 100644 third_party/assets/simple/clip_path_3.svg delete mode 100644 third_party/assets/simple/dash_path.svg delete mode 100644 third_party/assets/simple/ellipse.svg delete mode 100644 third_party/assets/simple/group_fill_opacity.svg delete mode 100644 third_party/assets/simple/group_opacity.svg delete mode 100644 third_party/assets/simple/linear_gradient.svg delete mode 100644 third_party/assets/simple/linear_gradient_2.svg delete mode 100644 third_party/assets/simple/linear_gradient_absolute_user_space_translate.svg delete mode 100644 third_party/assets/simple/linear_gradient_percentage_bounding_translate.svg delete mode 100644 third_party/assets/simple/linear_gradient_percentage_user_space_translate.svg delete mode 100644 third_party/assets/simple/nested_group.svg delete mode 100644 third_party/assets/simple/opacity_on_path.svg delete mode 100644 third_party/assets/simple/radial_gradient.svg delete mode 100644 third_party/assets/simple/radial_gradient_absolute_user_space_translate.svg delete mode 100644 third_party/assets/simple/radial_gradient_focal.svg delete mode 100644 third_party/assets/simple/radial_gradient_percentage_bounding_translate.svg delete mode 100644 third_party/assets/simple/radial_gradient_percentage_user_space_translate.svg delete mode 100644 third_party/assets/simple/rect_rrect.svg delete mode 100644 third_party/assets/simple/rect_rrect_no_ry.svg delete mode 100644 third_party/assets/simple/style_attr.svg delete mode 100644 third_party/assets/simple/text.svg delete mode 100644 third_party/assets/w3samples/aa.svg delete mode 100644 third_party/assets/w3samples/alphachannel.svg delete mode 100644 third_party/assets/wikimedia/Ghostscript_Tiger.svg delete mode 100644 third_party/assets/wikimedia/chess_knight.svg delete mode 100644 third_party/example/main.dart delete mode 100644 third_party/ios/.gitignore delete mode 100644 third_party/ios/Flutter/AppFrameworkInfo.plist delete mode 100644 third_party/ios/Flutter/Debug.xcconfig delete mode 100644 third_party/ios/Flutter/Release.xcconfig delete mode 100644 third_party/ios/Runner.xcodeproj/project.pbxproj delete mode 100644 third_party/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 third_party/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme delete mode 100644 third_party/ios/Runner.xcworkspace/contents.xcworkspacedata delete mode 100644 third_party/ios/Runner/AppDelegate.h delete mode 100644 third_party/ios/Runner/AppDelegate.m delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json delete mode 100644 third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png delete mode 100644 third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md delete mode 100644 third_party/ios/Runner/Base.lproj/LaunchScreen.storyboard delete mode 100644 third_party/ios/Runner/Base.lproj/Main.storyboard delete mode 100644 third_party/ios/Runner/Info.plist delete mode 100644 third_party/ios/Runner/main.m diff --git a/third_party/android/.gitignore b/third_party/android/.gitignore deleted file mode 100644 index 65b7315af1b6..000000000000 --- a/third_party/android/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -*.iml -*.class -.gradle -/local.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -/captures -GeneratedPluginRegistrant.java diff --git a/third_party/android/.project b/third_party/android/.project deleted file mode 100644 index 3964dd3f5b7f..000000000000 --- a/third_party/android/.project +++ /dev/null @@ -1,17 +0,0 @@ - - - android - Project android created by Buildship. - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.buildship.core.gradleprojectnature - - diff --git a/third_party/android/.settings/org.eclipse.buildship.core.prefs b/third_party/android/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index 9ddce8f000ed..000000000000 --- a/third_party/android/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Apr 28 20:14:23 EDT 2018 -connection.project.dir= diff --git a/third_party/android/app/.classpath b/third_party/android/app/.classpath deleted file mode 100644 index 8d8d85f14359..000000000000 --- a/third_party/android/app/.classpath +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/third_party/android/app/.project b/third_party/android/app/.project deleted file mode 100644 index ac485d7c3e62..000000000000 --- a/third_party/android/app/.project +++ /dev/null @@ -1,23 +0,0 @@ - - - app - Project app created by Buildship. - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.buildship.core.gradleprojectnature - - diff --git a/third_party/android/app/.settings/org.eclipse.buildship.core.prefs b/third_party/android/app/.settings/org.eclipse.buildship.core.prefs deleted file mode 100644 index a7d7283d48ce..000000000000 --- a/third_party/android/app/.settings/org.eclipse.buildship.core.prefs +++ /dev/null @@ -1,2 +0,0 @@ -#Sat Apr 28 20:14:23 EDT 2018 -connection.project.dir=.. diff --git a/third_party/android/app/build.gradle b/third_party/android/app/build.gradle deleted file mode 100644 index df6aec923086..000000000000 --- a/third_party/android/app/build.gradle +++ /dev/null @@ -1,51 +0,0 @@ -def localProperties = new Properties() -def localPropertiesFile = rootProject.file('local.properties') -if (localPropertiesFile.exists()) { - localPropertiesFile.withReader('UTF-8') { reader -> - localProperties.load(reader) - } -} - -def flutterRoot = localProperties.getProperty('flutter.sdk') -if (flutterRoot == null) { - throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") -} - -apply plugin: 'com.android.application' -apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" - -android { - compileSdkVersion 27 - - lintOptions { - disable 'InvalidPackage' - } - - defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.fluttersvg" - minSdkVersion 16 - targetSdkVersion 27 - versionCode 1 - versionName "1.0" - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } - - buildTypes { - release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. - signingConfig signingConfigs.debug - } - } -} - -flutter { - source '../..' -} - -dependencies { - testImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' -} diff --git a/third_party/android/app/src/main/AndroidManifest.xml b/third_party/android/app/src/main/AndroidManifest.xml deleted file mode 100644 index a1ba572ecb51..000000000000 --- a/third_party/android/app/src/main/AndroidManifest.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/third_party/android/app/src/main/java/com/example/fluttersvg/MainActivity.java b/third_party/android/app/src/main/java/com/example/fluttersvg/MainActivity.java deleted file mode 100644 index 99570dfffe80..000000000000 --- a/third_party/android/app/src/main/java/com/example/fluttersvg/MainActivity.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.example.fluttersvg; - -import android.os.Bundle; - -import io.flutter.app.FlutterActivity; -import io.flutter.plugins.GeneratedPluginRegistrant; - -public class MainActivity extends FlutterActivity { - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - GeneratedPluginRegistrant.registerWith(this); - } -} diff --git a/third_party/android/app/src/main/res/drawable/launch_background.xml b/third_party/android/app/src/main/res/drawable/launch_background.xml deleted file mode 100644 index 304732f88420..000000000000 --- a/third_party/android/app/src/main/res/drawable/launch_background.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - diff --git a/third_party/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/third_party/android/app/src/main/res/mipmap-hdpi/ic_launcher.png deleted file mode 100644 index db77bb4b7b0906d62b1847e87f15cdcacf6a4f29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ diff --git a/third_party/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/third_party/android/app/src/main/res/mipmap-mdpi/ic_launcher.png deleted file mode 100644 index 17987b79bb8a35cc66c3c1fd44f5a5526c1b78be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ diff --git a/third_party/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/third_party/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png deleted file mode 100644 index d5f1c8d34e7a88e3f88bea192c3a370d44689c3c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof diff --git a/third_party/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/third_party/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png deleted file mode 100644 index 4d6372eebdb28e45604e46eeda8dd24651419bc0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` diff --git a/third_party/android/app/src/main/res/values/styles.xml b/third_party/android/app/src/main/res/values/styles.xml deleted file mode 100644 index 00fa4417cfbe..000000000000 --- a/third_party/android/app/src/main/res/values/styles.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - diff --git a/third_party/android/build.gradle b/third_party/android/build.gradle deleted file mode 100644 index 447688755cf4..000000000000 --- a/third_party/android/build.gradle +++ /dev/null @@ -1,29 +0,0 @@ -buildscript { - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.0.1' - } -} - -allprojects { - repositories { - google() - jcenter() - } -} - -rootProject.buildDir = '../build' -subprojects { - project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { - project.evaluationDependsOn(':app') -} - -task clean(type: Delete) { - delete rootProject.buildDir -} diff --git a/third_party/android/gradle.properties b/third_party/android/gradle.properties deleted file mode 100644 index 8bd86f680510..000000000000 --- a/third_party/android/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M diff --git a/third_party/android/gradle/wrapper/gradle-wrapper.jar b/third_party/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 13372aef5e24af05341d49695ee84e5f9b594659..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53636 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ⅅ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 H-+%o-(+5aQ diff --git a/third_party/android/gradle/wrapper/gradle-wrapper.properties b/third_party/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index aa901e1e0db2..000000000000 --- a/third_party/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Fri Jun 23 08:50:38 CEST 2017 -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip diff --git a/third_party/android/gradlew b/third_party/android/gradlew deleted file mode 100755 index 9d82f7891513..000000000000 --- a/third_party/android/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/third_party/android/gradlew.bat b/third_party/android/gradlew.bat deleted file mode 100644 index aec99730b4e8..000000000000 --- a/third_party/android/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/third_party/android/settings.gradle b/third_party/android/settings.gradle deleted file mode 100644 index 5a2f14fb18f6..000000000000 --- a/third_party/android/settings.gradle +++ /dev/null @@ -1,15 +0,0 @@ -include ':app' - -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() - -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} - -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} diff --git a/third_party/assets/android_vd/battery_charging.xml b/third_party/assets/android_vd/battery_charging.xml deleted file mode 100644 index 61628a7602aa..000000000000 --- a/third_party/assets/android_vd/battery_charging.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/third_party/assets/dart.svg b/third_party/assets/dart.svg deleted file mode 100644 index 261e2bbf97da..000000000000 --- a/third_party/assets/dart.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/third_party/assets/deborah_ufw/new-action-expander.svg b/third_party/assets/deborah_ufw/new-action-expander.svg deleted file mode 100644 index 3cbd1068517c..000000000000 --- a/third_party/assets/deborah_ufw/new-action-expander.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - diff --git a/third_party/assets/deborah_ufw/new-camera.svg b/third_party/assets/deborah_ufw/new-camera.svg deleted file mode 100644 index b49e595b6c94..000000000000 --- a/third_party/assets/deborah_ufw/new-camera.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - diff --git a/third_party/assets/deborah_ufw/new-gif-button.svg b/third_party/assets/deborah_ufw/new-gif-button.svg deleted file mode 100644 index 2340bf1acfb6..000000000000 --- a/third_party/assets/deborah_ufw/new-gif-button.svg +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - diff --git a/third_party/assets/deborah_ufw/new-gif.svg b/third_party/assets/deborah_ufw/new-gif.svg deleted file mode 100644 index cf9e9cab65be..000000000000 --- a/third_party/assets/deborah_ufw/new-gif.svg +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - diff --git a/third_party/assets/deborah_ufw/new-image.svg b/third_party/assets/deborah_ufw/new-image.svg deleted file mode 100644 index ed41cff77c18..000000000000 --- a/third_party/assets/deborah_ufw/new-image.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - diff --git a/third_party/assets/deborah_ufw/new-mention.svg b/third_party/assets/deborah_ufw/new-mention.svg deleted file mode 100644 index 085a7d41b8b8..000000000000 --- a/third_party/assets/deborah_ufw/new-mention.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - diff --git a/third_party/assets/deborah_ufw/new-pause-button.svg b/third_party/assets/deborah_ufw/new-pause-button.svg deleted file mode 100644 index 90deeee9a5af..000000000000 --- a/third_party/assets/deborah_ufw/new-pause-button.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - diff --git a/third_party/assets/deborah_ufw/new-play-button.svg b/third_party/assets/deborah_ufw/new-play-button.svg deleted file mode 100644 index 40799c91370e..000000000000 --- a/third_party/assets/deborah_ufw/new-play-button.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - diff --git a/third_party/assets/deborah_ufw/new-send-circle.svg b/third_party/assets/deborah_ufw/new-send-circle.svg deleted file mode 100644 index ab58e6b145fd..000000000000 --- a/third_party/assets/deborah_ufw/new-send-circle.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/third_party/assets/deborah_ufw/numeric_25.svg b/third_party/assets/deborah_ufw/numeric_25.svg deleted file mode 100644 index ea6f38c2b3d8..000000000000 --- a/third_party/assets/deborah_ufw/numeric_25.svg +++ /dev/null @@ -1,19 +0,0 @@ - - - -icon-font/25/numeric_25 -Created with Sketch. - - - - diff --git a/third_party/assets/flutter_logo.svg b/third_party/assets/flutter_logo.svg deleted file mode 100644 index ec3d9144f352..000000000000 --- a/third_party/assets/flutter_logo.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/third_party/assets/simple/clip_path.svg b/third_party/assets/simple/clip_path.svg deleted file mode 100644 index d0877e91a4ff..000000000000 --- a/third_party/assets/simple/clip_path.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - diff --git a/third_party/assets/simple/clip_path_2.svg b/third_party/assets/simple/clip_path_2.svg deleted file mode 100644 index a9707d923da3..000000000000 --- a/third_party/assets/simple/clip_path_2.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/third_party/assets/simple/clip_path_3.svg b/third_party/assets/simple/clip_path_3.svg deleted file mode 100644 index aae181a1e7dc..000000000000 --- a/third_party/assets/simple/clip_path_3.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/third_party/assets/simple/dash_path.svg b/third_party/assets/simple/dash_path.svg deleted file mode 100644 index cbd5fa9a4b85..000000000000 --- a/third_party/assets/simple/dash_path.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/third_party/assets/simple/ellipse.svg b/third_party/assets/simple/ellipse.svg deleted file mode 100644 index 2ea45661cf0d..000000000000 --- a/third_party/assets/simple/ellipse.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/third_party/assets/simple/group_fill_opacity.svg b/third_party/assets/simple/group_fill_opacity.svg deleted file mode 100644 index 7a8e04f6604c..000000000000 --- a/third_party/assets/simple/group_fill_opacity.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/third_party/assets/simple/group_opacity.svg b/third_party/assets/simple/group_opacity.svg deleted file mode 100644 index 1bc0a7a7f548..000000000000 --- a/third_party/assets/simple/group_opacity.svg +++ /dev/null @@ -1,46 +0,0 @@ - - - - Example opacity01 - opacity property - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/third_party/assets/simple/linear_gradient.svg b/third_party/assets/simple/linear_gradient.svg deleted file mode 100644 index c0d45cdc5094..000000000000 --- a/third_party/assets/simple/linear_gradient.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/third_party/assets/simple/linear_gradient_2.svg b/third_party/assets/simple/linear_gradient_2.svg deleted file mode 100644 index eb75d36c2646..000000000000 --- a/third_party/assets/simple/linear_gradient_2.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - Example lingrad01 - fill a rectangle using a - linear gradient paint server - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/third_party/assets/simple/linear_gradient_absolute_user_space_translate.svg b/third_party/assets/simple/linear_gradient_absolute_user_space_translate.svg deleted file mode 100644 index ced5251b3e65..000000000000 --- a/third_party/assets/simple/linear_gradient_absolute_user_space_translate.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/third_party/assets/simple/linear_gradient_percentage_bounding_translate.svg b/third_party/assets/simple/linear_gradient_percentage_bounding_translate.svg deleted file mode 100644 index be1ef28c5502..000000000000 --- a/third_party/assets/simple/linear_gradient_percentage_bounding_translate.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/third_party/assets/simple/linear_gradient_percentage_user_space_translate.svg b/third_party/assets/simple/linear_gradient_percentage_user_space_translate.svg deleted file mode 100644 index c2b0ce07ffb1..000000000000 --- a/third_party/assets/simple/linear_gradient_percentage_user_space_translate.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/third_party/assets/simple/nested_group.svg b/third_party/assets/simple/nested_group.svg deleted file mode 100644 index 6f8472319a67..000000000000 --- a/third_party/assets/simple/nested_group.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/third_party/assets/simple/opacity_on_path.svg b/third_party/assets/simple/opacity_on_path.svg deleted file mode 100644 index 9f870d066e21..000000000000 --- a/third_party/assets/simple/opacity_on_path.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/third_party/assets/simple/radial_gradient.svg b/third_party/assets/simple/radial_gradient.svg deleted file mode 100644 index 42bcbd6e9038..000000000000 --- a/third_party/assets/simple/radial_gradient.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - Example radgrad01 - fill a rectangle by referencing a - radial gradient paint server - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/third_party/assets/simple/radial_gradient_absolute_user_space_translate.svg b/third_party/assets/simple/radial_gradient_absolute_user_space_translate.svg deleted file mode 100644 index 4268fea810d2..000000000000 --- a/third_party/assets/simple/radial_gradient_absolute_user_space_translate.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/third_party/assets/simple/radial_gradient_focal.svg b/third_party/assets/simple/radial_gradient_focal.svg deleted file mode 100644 index 862c829f50b3..000000000000 --- a/third_party/assets/simple/radial_gradient_focal.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/third_party/assets/simple/radial_gradient_percentage_bounding_translate.svg b/third_party/assets/simple/radial_gradient_percentage_bounding_translate.svg deleted file mode 100644 index 3fd58495c8b6..000000000000 --- a/third_party/assets/simple/radial_gradient_percentage_bounding_translate.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/third_party/assets/simple/radial_gradient_percentage_user_space_translate.svg b/third_party/assets/simple/radial_gradient_percentage_user_space_translate.svg deleted file mode 100644 index 303ff7d27ae3..000000000000 --- a/third_party/assets/simple/radial_gradient_percentage_user_space_translate.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/third_party/assets/simple/rect_rrect.svg b/third_party/assets/simple/rect_rrect.svg deleted file mode 100644 index 5960d185df26..000000000000 --- a/third_party/assets/simple/rect_rrect.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/third_party/assets/simple/rect_rrect_no_ry.svg b/third_party/assets/simple/rect_rrect_no_ry.svg deleted file mode 100644 index b98dd11995ca..000000000000 --- a/third_party/assets/simple/rect_rrect_no_ry.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/third_party/assets/simple/style_attr.svg b/third_party/assets/simple/style_attr.svg deleted file mode 100644 index 1c42fd79dd0f..000000000000 --- a/third_party/assets/simple/style_attr.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - diff --git a/third_party/assets/simple/text.svg b/third_party/assets/simple/text.svg deleted file mode 100644 index ac5bb68b079a..000000000000 --- a/third_party/assets/simple/text.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - Example text01 - 'Hello, out there' in blue - - - Hello, out there - - - - - \ No newline at end of file diff --git a/third_party/assets/w3samples/aa.svg b/third_party/assets/w3samples/aa.svg deleted file mode 100644 index 2f2d26b165a7..000000000000 --- a/third_party/assets/w3samples/aa.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/third_party/assets/w3samples/alphachannel.svg b/third_party/assets/w3samples/alphachannel.svg deleted file mode 100644 index be7bf45d07ee..000000000000 --- a/third_party/assets/w3samples/alphachannel.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/third_party/assets/wikimedia/Ghostscript_Tiger.svg b/third_party/assets/wikimedia/Ghostscript_Tiger.svg deleted file mode 100644 index 679edec2eb3f..000000000000 --- a/third_party/assets/wikimedia/Ghostscript_Tiger.svg +++ /dev/null @@ -1,725 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/third_party/assets/wikimedia/chess_knight.svg b/third_party/assets/wikimedia/chess_knight.svg deleted file mode 100644 index eabd2af51a23..000000000000 --- a/third_party/assets/wikimedia/chess_knight.svg +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - - - - - diff --git a/third_party/example/main.dart b/third_party/example/main.dart deleted file mode 100644 index 62d2098b6436..000000000000 --- a/third_party/example/main.dart +++ /dev/null @@ -1,168 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter_svg/avd.dart'; -import 'package:flutter_svg/flutter_svg.dart'; - -const List assetNames = const [ - // 'assets/notfound.svg', - 'assets/flutter_logo.svg', - 'assets/dart.svg', - 'assets/simple/clip_path_3.svg', - 'assets/simple/clip_path_2.svg', - 'assets/simple/clip_path.svg', - 'assets/simple/group_fill_opacity.svg', - 'assets/simple/group_opacity.svg', - 'assets/simple/text.svg', - 'assets/simple/linear_gradient.svg', - 'assets/simple/linear_gradient_2.svg', - 'assets/simple/radial_gradient.svg', - 'assets/simple/rect_rrect.svg', - 'assets/simple/rect_rrect_no_ry.svg', - 'assets/simple/style_attr.svg', - 'assets/w3samples/aa.svg', - 'assets/w3samples/alphachannel.svg', - 'assets/simple/ellipse.svg', - 'assets/simple/dash_path.svg', - 'assets/simple/nested_group.svg', - 'assets/wikimedia/chess_knight.svg', - 'assets/wikimedia/Ghostscript_Tiger.svg', -]; - -const List iconNames = const [ - 'assets/deborah_ufw/new-action-expander.svg', - 'assets/deborah_ufw/new-camera.svg', - 'assets/deborah_ufw/new-gif-button.svg', - 'assets/deborah_ufw/new-gif.svg', - 'assets/deborah_ufw/new-image.svg', - 'assets/deborah_ufw/new-mention.svg', - 'assets/deborah_ufw/new-pause-button.svg', - 'assets/deborah_ufw/new-play-button.svg', - 'assets/deborah_ufw/new-send-circle.svg', - 'assets/deborah_ufw/numeric_25.svg', -]; - -const List uriNames = const [ - 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', - 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', -]; - -void main() { - runApp(new MyApp()); -} - -class MyApp extends StatelessWidget { - // This widget is the root of your application. - @override - Widget build(BuildContext context) { - return new MaterialApp( - title: 'Flutter Demo', - theme: new ThemeData( - primarySwatch: Colors.blue, - ), - home: const MyHomePage(title: 'Flutter SVG Demo'), - ); - } -} - -class MyHomePage extends StatefulWidget { - const MyHomePage({Key key, this.title}) : super(key: key); - final String title; - - @override - _MyHomePageState createState() => new _MyHomePageState(); -} - -class _MyHomePageState extends State { - final List _painters = []; - double _dimension; - - @override - void initState() { - super.initState(); - _dimension = 250.0; - - _painters.add(new SvgPicture.string( - ''' - - - - - - -''')); - - for (String assetName in assetNames) { - _painters.add( - new SvgPicture.asset(assetName), - ); - } - - for (int i = 0; i < iconNames.length; i++) { - _painters.add( - new Directionality( - textDirection: TextDirection.ltr, - child: new SvgPicture.asset( - iconNames[i], - color: Colors.blueGrey[(i + 1) * 100], - matchTextDirection: true, - ), - ), - ); - } - - // _painters.add(new SvgPicture.asset(iconNames[0], color: Colors.red)); - - for (String uriName in uriNames) { - _painters.add( - new SvgPicture.network( - uriName, - placeholderBuilder: (BuildContext context) => new Container( - padding: const EdgeInsets.all(30.0), - child: const CircularProgressIndicator()), - ), - ); - } - _painters - .add(new AvdPicture.asset('assets/android_vd/battery_charging.xml')); - } - - @override - Widget build(BuildContext context) { - if (_dimension > MediaQuery.of(context).size.width - 10.0) { - _dimension = MediaQuery.of(context).size.width - 10.0; - } - return new Scaffold( - appBar: new AppBar( - title: new Text(widget.title), - ), - body: new Column(children: [ - new Slider( - min: 5.0, - max: MediaQuery.of(context).size.width - 10.0, - value: _dimension, - onChanged: (double val) { - setState(() => _dimension = val); - }), - // new FlutterLogo(size: _dimension), - // new Container( - // padding: const EdgeInsets.all(12.0), - // child: - - // ) - new Expanded( - child: new GridView.extent( - shrinkWrap: true, - maxCrossAxisExtent: _dimension, - padding: const EdgeInsets.all(4.0), - mainAxisSpacing: 4.0, - crossAxisSpacing: 4.0, - children: _painters.toList(), - ), - ), - ]), - ); - } -} diff --git a/third_party/ios/.gitignore b/third_party/ios/.gitignore deleted file mode 100644 index 1e1aafd63360..000000000000 --- a/third_party/ios/.gitignore +++ /dev/null @@ -1,42 +0,0 @@ -.idea/ -.vagrant/ -.sconsign.dblite -.svn/ - -.DS_Store -*.swp -profile - -DerivedData/ -build/ -GeneratedPluginRegistrant.h -GeneratedPluginRegistrant.m - -*.pbxuser -*.mode1v3 -*.mode2v3 -*.perspectivev3 - -!default.pbxuser -!default.mode1v3 -!default.mode2v3 -!default.perspectivev3 - -xcuserdata - -*.moved-aside - -*.pyc -*sync/ -Icon? -.tags* - -/Flutter/app.flx -/Flutter/app.zip -/Flutter/flutter_assets/ -/Flutter/App.framework -/Flutter/Flutter.framework -/Flutter/Generated.xcconfig -/ServiceDefinitions.json - -Pods/ diff --git a/third_party/ios/Flutter/AppFrameworkInfo.plist b/third_party/ios/Flutter/AppFrameworkInfo.plist deleted file mode 100644 index 6c2de8086bcd..000000000000 --- a/third_party/ios/Flutter/AppFrameworkInfo.plist +++ /dev/null @@ -1,30 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - UIRequiredDeviceCapabilities - - arm64 - - MinimumOSVersion - 8.0 - - diff --git a/third_party/ios/Flutter/Debug.xcconfig b/third_party/ios/Flutter/Debug.xcconfig deleted file mode 100644 index 592ceee85b89..000000000000 --- a/third_party/ios/Flutter/Debug.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Generated.xcconfig" diff --git a/third_party/ios/Flutter/Release.xcconfig b/third_party/ios/Flutter/Release.xcconfig deleted file mode 100644 index 592ceee85b89..000000000000 --- a/third_party/ios/Flutter/Release.xcconfig +++ /dev/null @@ -1 +0,0 @@ -#include "Generated.xcconfig" diff --git a/third_party/ios/Runner.xcodeproj/project.pbxproj b/third_party/ios/Runner.xcodeproj/project.pbxproj deleted file mode 100644 index f823283cee5b..000000000000 --- a/third_party/ios/Runner.xcodeproj/project.pbxproj +++ /dev/null @@ -1,436 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; - 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; - 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; -/* End PBXBuildFile section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 9705A1C41CF9048500538489 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, - 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; - 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; - 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; - 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; - 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; - 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; - 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 97C146EB1CF9000F007C117D /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, - 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 9740EEB11CF90186004384FC /* Flutter */ = { - isa = PBXGroup; - children = ( - 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, - 3B80C3931E831B6300D905FE /* App.framework */, - 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, - 9740EEBA1CF902C7004384FC /* Flutter.framework */, - 9740EEB21CF90195004384FC /* Debug.xcconfig */, - 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, - 9740EEB31CF90195004384FC /* Generated.xcconfig */, - ); - name = Flutter; - sourceTree = ""; - }; - 97C146E51CF9000F007C117D = { - isa = PBXGroup; - children = ( - 9740EEB11CF90186004384FC /* Flutter */, - 97C146F01CF9000F007C117D /* Runner */, - 97C146EF1CF9000F007C117D /* Products */, - CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, - ); - sourceTree = ""; - }; - 97C146EF1CF9000F007C117D /* Products */ = { - isa = PBXGroup; - children = ( - 97C146EE1CF9000F007C117D /* Runner.app */, - ); - name = Products; - sourceTree = ""; - }; - 97C146F01CF9000F007C117D /* Runner */ = { - isa = PBXGroup; - children = ( - 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, - 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, - 97C146FA1CF9000F007C117D /* Main.storyboard */, - 97C146FD1CF9000F007C117D /* Assets.xcassets */, - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, - 97C147021CF9000F007C117D /* Info.plist */, - 97C146F11CF9000F007C117D /* Supporting Files */, - 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, - 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, - ); - path = Runner; - sourceTree = ""; - }; - 97C146F11CF9000F007C117D /* Supporting Files */ = { - isa = PBXGroup; - children = ( - 97C146F21CF9000F007C117D /* main.m */, - ); - name = "Supporting Files"; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 97C146ED1CF9000F007C117D /* Runner */ = { - isa = PBXNativeTarget; - buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; - buildPhases = ( - 9740EEB61CF901F6004384FC /* Run Script */, - 97C146EA1CF9000F007C117D /* Sources */, - 97C146EB1CF9000F007C117D /* Frameworks */, - 97C146EC1CF9000F007C117D /* Resources */, - 9705A1C41CF9048500538489 /* Embed Frameworks */, - 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = Runner; - productName = Runner; - productReference = 97C146EE1CF9000F007C117D /* Runner.app */; - productType = "com.apple.product-type.application"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 97C146E61CF9000F007C117D /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0910; - ORGANIZATIONNAME = "The Chromium Authors"; - TargetAttributes = { - 97C146ED1CF9000F007C117D = { - CreatedOnToolsVersion = 7.3.1; - }; - }; - }; - buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 97C146E51CF9000F007C117D; - productRefGroup = 97C146EF1CF9000F007C117D /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 97C146ED1CF9000F007C117D /* Runner */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 97C146EC1CF9000F007C117D /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, - 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */, - 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, - 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, - 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, - 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, - 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Thin Binary"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; - }; - 9740EEB61CF901F6004384FC /* Run Script */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "Run Script"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 97C146EA1CF9000F007C117D /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, - 97C146F31CF9000F007C117D /* main.m in Sources */, - 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXVariantGroup section */ - 97C146FA1CF9000F007C117D /* Main.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C146FB1CF9000F007C117D /* Base */, - ); - name = Main.storyboard; - sourceTree = ""; - }; - 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { - isa = PBXVariantGroup; - children = ( - 97C147001CF9000F007C117D /* Base */, - ); - name = LaunchScreen.storyboard; - sourceTree = ""; - }; -/* End PBXVariantGroup section */ - -/* Begin XCBuildConfiguration section */ - 97C147031CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 97C147041CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - MTL_ENABLE_DEBUG_INFO = NO; - SDKROOT = iphoneos; - TARGETED_DEVICE_FAMILY = "1,2"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 97C147061CF9000F007C117D /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; - buildSettings = { - ARCHS = arm64; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterSvg; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - 97C147071CF9000F007C117D /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; - buildSettings = { - ARCHS = arm64; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); - PRODUCT_BUNDLE_IDENTIFIER = com.example.flutterSvg; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147031CF9000F007C117D /* Debug */, - 97C147041CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 97C147061CF9000F007C117D /* Debug */, - 97C147071CF9000F007C117D /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 97C146E61CF9000F007C117D /* Project object */; -} diff --git a/third_party/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/third_party/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16ed0f..000000000000 --- a/third_party/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/third_party/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/third_party/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme deleted file mode 100644 index 1263ac84b105..000000000000 --- a/third_party/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/third_party/ios/Runner.xcworkspace/contents.xcworkspacedata b/third_party/ios/Runner.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 1d526a16ed0f..000000000000 --- a/third_party/ios/Runner.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/third_party/ios/Runner/AppDelegate.h b/third_party/ios/Runner/AppDelegate.h deleted file mode 100644 index cf210d213f27..000000000000 --- a/third_party/ios/Runner/AppDelegate.h +++ /dev/null @@ -1,6 +0,0 @@ -#import -#import - -@interface AppDelegate : FlutterAppDelegate - -@end diff --git a/third_party/ios/Runner/AppDelegate.m b/third_party/ios/Runner/AppDelegate.m deleted file mode 100644 index 112becd13b36..000000000000 --- a/third_party/ios/Runner/AppDelegate.m +++ /dev/null @@ -1,12 +0,0 @@ -#include "AppDelegate.h" -#include "GeneratedPluginRegistrant.h" - -@implementation AppDelegate - -- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - [GeneratedPluginRegistrant registerWithRegistry:self]; - // Override point for customization after application launch. - return [super application:application didFinishLaunchingWithOptions:launchOptions]; -} - -@end diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index d36b1fab2d9d..000000000000 --- a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,122 +0,0 @@ -{ - "images" : [ - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "20x20", - "idiom" : "iphone", - "filename" : "Icon-App-20x20@3x.png", - "scale" : "3x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "iphone", - "filename" : "Icon-App-29x29@3x.png", - "scale" : "3x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "iphone", - "filename" : "Icon-App-40x40@3x.png", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@2x.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "Icon-App-60x60@3x.png", - "scale" : "3x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@1x.png", - "scale" : "1x" - }, - { - "size" : "20x20", - "idiom" : "ipad", - "filename" : "Icon-App-20x20@2x.png", - "scale" : "2x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@1x.png", - "scale" : "1x" - }, - { - "size" : "29x29", - "idiom" : "ipad", - "filename" : "Icon-App-29x29@2x.png", - "scale" : "2x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@1x.png", - "scale" : "1x" - }, - { - "size" : "40x40", - "idiom" : "ipad", - "filename" : "Icon-App-40x40@2x.png", - "scale" : "2x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@1x.png", - "scale" : "1x" - }, - { - "size" : "76x76", - "idiom" : "ipad", - "filename" : "Icon-App-76x76@2x.png", - "scale" : "2x" - }, - { - "size" : "83.5x83.5", - "idiom" : "ipad", - "filename" : "Icon-App-83.5x83.5@2x.png", - "scale" : "2x" - }, - { - "size" : "1024x1024", - "idiom" : "ios-marketing", - "filename" : "Icon-App-1024x1024@1x.png", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png deleted file mode 100644 index 3d43d11e66f4de3da27ed045ca4fe38ad8b48094..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11112 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 P-1+_A+?hGkL;m(J7kc&K diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png deleted file mode 100644 index 28c6bf03016f6c994b70f38d1b7346e5831b531f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png deleted file mode 100644 index f091b6b0bca859a3f474b03065bef75ba58a9e4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png deleted file mode 100644 index d0ef06e7edb86cdfe0d15b4b0d98334a86163658..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1716 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 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png deleted file mode 100644 index c8f9ed8f5cee1c98386d13b17e89f719e83555b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png deleted file mode 100644 index a6d6b8609df07bf62e5100a53a01510388bd2b22..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png deleted file mode 100644 index 75b2d164a5a98e212cca15ea7bf2ab5de5108680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3831 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 diff --git a/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/third_party/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png deleted file mode 100644 index c4df70d39da7941ef3f6dcb7f06a192d8dcb308d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png deleted file mode 100644 index 9da19eacad3b03bb08bbddbbf4ac48dd78b3d838..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v diff --git a/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md deleted file mode 100644 index 89c2725b70f1..000000000000 --- a/third_party/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# Launch Screen Assets - -You can customize the launch screen with your own desired assets by replacing the image files in this directory. - -You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/third_party/ios/Runner/Base.lproj/LaunchScreen.storyboard b/third_party/ios/Runner/Base.lproj/LaunchScreen.storyboard deleted file mode 100644 index f2e259c7c939..000000000000 --- a/third_party/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/third_party/ios/Runner/Base.lproj/Main.storyboard b/third_party/ios/Runner/Base.lproj/Main.storyboard deleted file mode 100644 index f3c28516fb38..000000000000 --- a/third_party/ios/Runner/Base.lproj/Main.storyboard +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/third_party/ios/Runner/Info.plist b/third_party/ios/Runner/Info.plist deleted file mode 100644 index 59d7e309a41b..000000000000 --- a/third_party/ios/Runner/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - flutter_svg - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UIRequiredDeviceCapabilities - - arm64 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - - diff --git a/third_party/ios/Runner/main.m b/third_party/ios/Runner/main.m deleted file mode 100644 index 0ccc450011c4..000000000000 --- a/third_party/ios/Runner/main.m +++ /dev/null @@ -1,9 +0,0 @@ -#import -#import -#import "AppDelegate.h" - -int main(int argc, char * argv[]) { - @autoreleasepool { - return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); - } -} diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index a9a447538aae..a148e9072680 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -410,4 +410,4 @@ packages: version: "2.1.15" sdks: dart: ">=2.0.0-dev.69.0 <3.0.0" - flutter: ">=0.5.1 <2.0.0" + flutter: ">=0.7.3 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 8c468d30f71f..2490ad1b7653 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -19,30 +19,9 @@ dev_dependencies: flutter_test: sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/ - - assets/w3samples/ - - assets/deborah_ufw/ - - assets/simple/ - - assets/wikimedia/ - - assets/android_vd/ - environment: sdk: ">=1.19.0 <3.0.0" - flutter: ">=0.5.1 <2.0.0" + flutter: ">=0.7.3 <2.0.0" # dependency_overrides: # sky_engine: diff --git a/third_party/test/golden_svg_test.dart b/third_party/test/golden_svg_test.dart index 3d4a1c22386c..f1e606883b02 100644 --- a/third_party/test/golden_svg_test.dart +++ b/third_party/test/golden_svg_test.dart @@ -20,8 +20,8 @@ Iterable getGoldenFileNames() sync* { String getSvgAssetName(String goldenFileName) { return goldenFileName - .replaceAll('/golden/', '/assets/') - .replaceAll('\\golden\\', '\\assets\\') + .replaceAll('/golden/', '/example/assets/') + .replaceAll('\\golden\\', '\\example\\assets\\') .replaceAll('.png', '.svg'); } diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index 59572c2ff3d1..be875230a872 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -41,7 +41,7 @@ final Set badSvgFiles = new Set.of([ ]); Iterable getSvgFileNames() sync* { - final Directory dir = new Directory('./assets'); + final Directory dir = new Directory('./example/assets'); for (FileSystemEntity fe in dir.listSync(recursive: true)) { if (fe is File && fe.path.toLowerCase().endsWith('.svg') && @@ -54,8 +54,8 @@ Iterable getSvgFileNames() sync* { String getGoldenFileName(String svgAssetPath) { return svgAssetPath - .replaceAll('/assets/', '/golden/') - .replaceAll('\\assets\\', '\\golden\\') + .replaceAll('/example\/assets/', '/golden/') + .replaceAll('\\example\\assets\\', '\\golden\\') .replaceAll('.svg', '.png'); } From 5dda1393c560640decea6a5555f365a5b34c0276 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Sep 2018 20:11:50 -0700 Subject: [PATCH 146/512] restructure for newer flutter versions, update goldens --- third_party/example/.gitignore | 9 + third_party/example/.metadata | 8 + third_party/example/README.md | 8 + third_party/example/android/.gitignore | 10 + third_party/example/android/app/build.gradle | 61 ++ .../android/app/src/main/AndroidManifest.xml | 39 + .../com/example/example/MainActivity.java | 13 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../app/src/main/res/values/styles.xml | 8 + third_party/example/android/build.gradle | 29 + third_party/example/android/gradle.properties | 1 + .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + third_party/example/android/gradlew | 160 ++++ third_party/example/android/gradlew.bat | 90 +++ third_party/example/android/settings.gradle | 15 + .../assets/android_vd/battery_charging.xml | 22 + third_party/example/assets/dart.svg | 50 ++ .../deborah_ufw/new-action-expander.svg | 14 + .../example/assets/deborah_ufw/new-camera.svg | 21 + .../assets/deborah_ufw/new-gif-button.svg | 32 + .../example/assets/deborah_ufw/new-gif.svg | 30 + .../example/assets/deborah_ufw/new-image.svg | 19 + .../assets/deborah_ufw/new-mention.svg | 22 + .../assets/deborah_ufw/new-pause-button.svg | 22 + .../assets/deborah_ufw/new-play-button.svg | 16 + .../assets/deborah_ufw/new-send-circle.svg | 27 + .../example/assets/deborah_ufw/numeric_25.svg | 19 + third_party/example/assets/flutter_logo.svg | 20 + .../example/assets/simple/clip_path.svg | 13 + .../example/assets/simple/clip_path_2.svg | 9 + .../example/assets/simple/clip_path_3.svg | 13 + .../example/assets/simple/dash_path.svg | 14 + third_party/example/assets/simple/ellipse.svg | 5 + .../assets/simple/group_fill_opacity.svg | 28 + .../example/assets/simple/group_opacity.svg | 46 ++ .../example/assets/simple/linear_gradient.svg | 11 + .../assets/simple/linear_gradient_2.svg | 24 + ...gradient_absolute_user_space_translate.svg | 9 + ...gradient_percentage_bounding_translate.svg | 9 + ...adient_percentage_user_space_translate.svg | 9 + .../example/assets/simple/nested_group.svg | 8 + .../example/assets/simple/opacity_on_path.svg | 3 + .../example/assets/simple/radial_gradient.svg | 26 + ...gradient_absolute_user_space_translate.svg | 9 + .../assets/simple/radial_gradient_focal.svg | 13 + ...gradient_percentage_bounding_translate.svg | 9 + ...adient_percentage_user_space_translate.svg | 9 + .../example/assets/simple/rect_rrect.svg | 6 + .../assets/simple/rect_rrect_no_ry.svg | 3 + .../example/assets/simple/style_attr.svg | 6 + third_party/example/assets/simple/text.svg | 16 + third_party/example/assets/w3samples/aa.svg | 5 + .../example/assets/w3samples/alphachannel.svg | 5 + .../assets/wikimedia/Firefox_Logo_2017.svg | 139 ++++ .../assets/wikimedia/Ghostscript_Tiger.svg | 725 ++++++++++++++++++ .../example/assets/wikimedia/chess_knight.svg | 23 + third_party/example/example.iml | 18 + third_party/example/example_android.iml | 27 + third_party/example/ios/.gitignore | 45 ++ .../ios/Flutter/AppFrameworkInfo.plist | 26 + .../example/ios/Flutter/Debug.xcconfig | 1 + .../example/ios/Flutter/Release.xcconfig | 1 + .../ios/Runner.xcodeproj/project.pbxproj | 436 +++++++++++ .../contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/Runner.xcscheme | 93 +++ .../contents.xcworkspacedata | 7 + third_party/example/ios/Runner/AppDelegate.h | 6 + third_party/example/ios/Runner/AppDelegate.m | 13 + .../AppIcon.appiconset/Contents.json | 122 +++ .../Icon-App-1024x1024@1x.png | Bin 0 -> 11112 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 564 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 1588 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 1025 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 1716 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 1920 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 1895 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 3831 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 1888 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 3294 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 3612 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + .../Runner/Base.lproj/LaunchScreen.storyboard | 37 + .../ios/Runner/Base.lproj/Main.storyboard | 26 + third_party/example/ios/Runner/Info.plist | 45 ++ third_party/example/ios/Runner/main.m | 9 + third_party/example/lib/main.dart | 169 ++++ third_party/example/pubspec.lock | 79 ++ third_party/example/pubspec.yaml | 41 + .../golden/wikimedia/Firefox_Logo_2017.png | Bin 0 -> 24368 bytes .../golden/wikimedia/Ghostscript_Tiger.png | Bin 44529 -> 44535 bytes .../test/golden_widget/flutter_logo.asset.png | Bin 9850 -> 11111 bytes .../golden_widget/flutter_logo.memory.png | Bin 9850 -> 11111 bytes .../golden_widget/flutter_logo.network.png | Bin 9850 -> 11111 bytes .../golden_widget/flutter_logo.string.png | Bin 9850 -> 11111 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 10447 -> 11653 bytes third_party/tool/gen_golden.dart | 1 + 110 files changed, 3215 insertions(+) create mode 100644 third_party/example/.gitignore create mode 100644 third_party/example/.metadata create mode 100644 third_party/example/README.md create mode 100644 third_party/example/android/.gitignore create mode 100644 third_party/example/android/app/build.gradle create mode 100644 third_party/example/android/app/src/main/AndroidManifest.xml create mode 100644 third_party/example/android/app/src/main/java/com/example/example/MainActivity.java create mode 100644 third_party/example/android/app/src/main/res/drawable/launch_background.xml create mode 100644 third_party/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 third_party/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 third_party/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 third_party/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 third_party/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 third_party/example/android/app/src/main/res/values/styles.xml create mode 100644 third_party/example/android/build.gradle create mode 100644 third_party/example/android/gradle.properties create mode 100644 third_party/example/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 third_party/example/android/gradle/wrapper/gradle-wrapper.properties create mode 100755 third_party/example/android/gradlew create mode 100644 third_party/example/android/gradlew.bat create mode 100644 third_party/example/android/settings.gradle create mode 100644 third_party/example/assets/android_vd/battery_charging.xml create mode 100644 third_party/example/assets/dart.svg create mode 100644 third_party/example/assets/deborah_ufw/new-action-expander.svg create mode 100644 third_party/example/assets/deborah_ufw/new-camera.svg create mode 100644 third_party/example/assets/deborah_ufw/new-gif-button.svg create mode 100644 third_party/example/assets/deborah_ufw/new-gif.svg create mode 100644 third_party/example/assets/deborah_ufw/new-image.svg create mode 100644 third_party/example/assets/deborah_ufw/new-mention.svg create mode 100644 third_party/example/assets/deborah_ufw/new-pause-button.svg create mode 100644 third_party/example/assets/deborah_ufw/new-play-button.svg create mode 100644 third_party/example/assets/deborah_ufw/new-send-circle.svg create mode 100644 third_party/example/assets/deborah_ufw/numeric_25.svg create mode 100644 third_party/example/assets/flutter_logo.svg create mode 100644 third_party/example/assets/simple/clip_path.svg create mode 100644 third_party/example/assets/simple/clip_path_2.svg create mode 100644 third_party/example/assets/simple/clip_path_3.svg create mode 100644 third_party/example/assets/simple/dash_path.svg create mode 100644 third_party/example/assets/simple/ellipse.svg create mode 100644 third_party/example/assets/simple/group_fill_opacity.svg create mode 100644 third_party/example/assets/simple/group_opacity.svg create mode 100644 third_party/example/assets/simple/linear_gradient.svg create mode 100644 third_party/example/assets/simple/linear_gradient_2.svg create mode 100644 third_party/example/assets/simple/linear_gradient_absolute_user_space_translate.svg create mode 100644 third_party/example/assets/simple/linear_gradient_percentage_bounding_translate.svg create mode 100644 third_party/example/assets/simple/linear_gradient_percentage_user_space_translate.svg create mode 100644 third_party/example/assets/simple/nested_group.svg create mode 100644 third_party/example/assets/simple/opacity_on_path.svg create mode 100644 third_party/example/assets/simple/radial_gradient.svg create mode 100644 third_party/example/assets/simple/radial_gradient_absolute_user_space_translate.svg create mode 100644 third_party/example/assets/simple/radial_gradient_focal.svg create mode 100644 third_party/example/assets/simple/radial_gradient_percentage_bounding_translate.svg create mode 100644 third_party/example/assets/simple/radial_gradient_percentage_user_space_translate.svg create mode 100644 third_party/example/assets/simple/rect_rrect.svg create mode 100644 third_party/example/assets/simple/rect_rrect_no_ry.svg create mode 100644 third_party/example/assets/simple/style_attr.svg create mode 100644 third_party/example/assets/simple/text.svg create mode 100644 third_party/example/assets/w3samples/aa.svg create mode 100644 third_party/example/assets/w3samples/alphachannel.svg create mode 100644 third_party/example/assets/wikimedia/Firefox_Logo_2017.svg create mode 100644 third_party/example/assets/wikimedia/Ghostscript_Tiger.svg create mode 100644 third_party/example/assets/wikimedia/chess_knight.svg create mode 100644 third_party/example/example.iml create mode 100644 third_party/example/example_android.iml create mode 100644 third_party/example/ios/.gitignore create mode 100644 third_party/example/ios/Flutter/AppFrameworkInfo.plist create mode 100644 third_party/example/ios/Flutter/Debug.xcconfig create mode 100644 third_party/example/ios/Flutter/Release.xcconfig create mode 100644 third_party/example/ios/Runner.xcodeproj/project.pbxproj create mode 100644 third_party/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 third_party/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 third_party/example/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 third_party/example/ios/Runner/AppDelegate.h create mode 100644 third_party/example/ios/Runner/AppDelegate.m create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 third_party/example/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 third_party/example/ios/Runner/Base.lproj/Main.storyboard create mode 100644 third_party/example/ios/Runner/Info.plist create mode 100644 third_party/example/ios/Runner/main.m create mode 100644 third_party/example/lib/main.dart create mode 100644 third_party/example/pubspec.lock create mode 100644 third_party/example/pubspec.yaml create mode 100644 third_party/golden/wikimedia/Firefox_Logo_2017.png diff --git a/third_party/example/.gitignore b/third_party/example/.gitignore new file mode 100644 index 000000000000..dee655cc42ea --- /dev/null +++ b/third_party/example/.gitignore @@ -0,0 +1,9 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +build/ + +.flutter-plugins diff --git a/third_party/example/.metadata b/third_party/example/.metadata new file mode 100644 index 000000000000..e9290cdb98f2 --- /dev/null +++ b/third_party/example/.metadata @@ -0,0 +1,8 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: d194c25bef494053b0fb6c5be4b9d46f909cad3a + channel: hide_fab diff --git a/third_party/example/README.md b/third_party/example/README.md new file mode 100644 index 000000000000..64a12f6bc582 --- /dev/null +++ b/third_party/example/README.md @@ -0,0 +1,8 @@ +# example + +A new Flutter project. + +## Getting Started + +For help getting started with Flutter, view our online +[documentation](https://flutter.io/). diff --git a/third_party/example/android/.gitignore b/third_party/example/android/.gitignore new file mode 100644 index 000000000000..65b7315af1b6 --- /dev/null +++ b/third_party/example/android/.gitignore @@ -0,0 +1,10 @@ +*.iml +*.class +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +GeneratedPluginRegistrant.java diff --git a/third_party/example/android/app/build.gradle b/third_party/example/android/app/build.gradle new file mode 100644 index 000000000000..3d260e6cc59e --- /dev/null +++ b/third_party/example/android/app/build.gradle @@ -0,0 +1,61 @@ +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterRoot = localProperties.getProperty('flutter.sdk') +if (flutterRoot == null) { + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +apply plugin: 'com.android.application' +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" + +android { + compileSdkVersion 27 + + lintOptions { + disable 'InvalidPackage' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.example" + minSdkVersion 16 + targetSdkVersion 27 + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies { + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' +} diff --git a/third_party/example/android/app/src/main/AndroidManifest.xml b/third_party/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..1b515f8b47d1 --- /dev/null +++ b/third_party/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + diff --git a/third_party/example/android/app/src/main/java/com/example/example/MainActivity.java b/third_party/example/android/app/src/main/java/com/example/example/MainActivity.java new file mode 100644 index 000000000000..84f8920f66f9 --- /dev/null +++ b/third_party/example/android/app/src/main/java/com/example/example/MainActivity.java @@ -0,0 +1,13 @@ +package com.example.example; + +import android.os.Bundle; +import io.flutter.app.FlutterActivity; +import io.flutter.plugins.GeneratedPluginRegistrant; + +public class MainActivity extends FlutterActivity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + GeneratedPluginRegistrant.registerWith(this); + } +} diff --git a/third_party/example/android/app/src/main/res/drawable/launch_background.xml b/third_party/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 000000000000..304732f88420 --- /dev/null +++ b/third_party/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/third_party/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/third_party/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 diff --git a/third_party/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/third_party/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 diff --git a/third_party/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/third_party/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 diff --git a/third_party/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/third_party/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/third_party/example/android/app/src/main/res/values/styles.xml b/third_party/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 000000000000..00fa4417cfbe --- /dev/null +++ b/third_party/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,8 @@ + + + + diff --git a/third_party/example/android/build.gradle b/third_party/example/android/build.gradle new file mode 100644 index 000000000000..d4225c7905bc --- /dev/null +++ b/third_party/example/android/build.gradle @@ -0,0 +1,29 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.1.2' + } +} + +allprojects { + repositories { + google() + jcenter() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/third_party/example/android/gradle.properties b/third_party/example/android/gradle.properties new file mode 100644 index 000000000000..8bd86f680510 --- /dev/null +++ b/third_party/example/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/third_party/example/android/gradle/wrapper/gradle-wrapper.jar b/third_party/example/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..13372aef5e24af05341d49695ee84e5f9b594659 GIT binary patch literal 53636 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ⅅ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 H-+%o-(+5aQ literal 0 HcmV?d00001 diff --git a/third_party/example/android/gradle/wrapper/gradle-wrapper.properties b/third_party/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..9372d0f3f41a --- /dev/null +++ b/third_party/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Jun 23 08:50:38 CEST 2017 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip diff --git a/third_party/example/android/gradlew b/third_party/example/android/gradlew new file mode 100755 index 000000000000..9d82f7891513 --- /dev/null +++ b/third_party/example/android/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/third_party/example/android/gradlew.bat b/third_party/example/android/gradlew.bat new file mode 100644 index 000000000000..aec99730b4e8 --- /dev/null +++ b/third_party/example/android/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/third_party/example/android/settings.gradle b/third_party/example/android/settings.gradle new file mode 100644 index 000000000000..5a2f14fb18f6 --- /dev/null +++ b/third_party/example/android/settings.gradle @@ -0,0 +1,15 @@ +include ':app' + +def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() + +def plugins = new Properties() +def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') +if (pluginsFile.exists()) { + pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } +} + +plugins.each { name, path -> + def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() + include ":$name" + project(":$name").projectDir = pluginDirectory +} diff --git a/third_party/example/assets/android_vd/battery_charging.xml b/third_party/example/assets/android_vd/battery_charging.xml new file mode 100644 index 000000000000..61628a7602aa --- /dev/null +++ b/third_party/example/assets/android_vd/battery_charging.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/dart.svg b/third_party/example/assets/dart.svg new file mode 100644 index 000000000000..261e2bbf97da --- /dev/null +++ b/third_party/example/assets/dart.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/example/assets/deborah_ufw/new-action-expander.svg b/third_party/example/assets/deborah_ufw/new-action-expander.svg new file mode 100644 index 000000000000..3cbd1068517c --- /dev/null +++ b/third_party/example/assets/deborah_ufw/new-action-expander.svg @@ -0,0 +1,14 @@ + + + + + + + + diff --git a/third_party/example/assets/deborah_ufw/new-camera.svg b/third_party/example/assets/deborah_ufw/new-camera.svg new file mode 100644 index 000000000000..b49e595b6c94 --- /dev/null +++ b/third_party/example/assets/deborah_ufw/new-camera.svg @@ -0,0 +1,21 @@ + + + + + + + diff --git a/third_party/example/assets/deborah_ufw/new-gif-button.svg b/third_party/example/assets/deborah_ufw/new-gif-button.svg new file mode 100644 index 000000000000..2340bf1acfb6 --- /dev/null +++ b/third_party/example/assets/deborah_ufw/new-gif-button.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + diff --git a/third_party/example/assets/deborah_ufw/new-gif.svg b/third_party/example/assets/deborah_ufw/new-gif.svg new file mode 100644 index 000000000000..cf9e9cab65be --- /dev/null +++ b/third_party/example/assets/deborah_ufw/new-gif.svg @@ -0,0 +1,30 @@ + + + + + + + + + + diff --git a/third_party/example/assets/deborah_ufw/new-image.svg b/third_party/example/assets/deborah_ufw/new-image.svg new file mode 100644 index 000000000000..ed41cff77c18 --- /dev/null +++ b/third_party/example/assets/deborah_ufw/new-image.svg @@ -0,0 +1,19 @@ + + + + + + + + diff --git a/third_party/example/assets/deborah_ufw/new-mention.svg b/third_party/example/assets/deborah_ufw/new-mention.svg new file mode 100644 index 000000000000..085a7d41b8b8 --- /dev/null +++ b/third_party/example/assets/deborah_ufw/new-mention.svg @@ -0,0 +1,22 @@ + + + + + diff --git a/third_party/example/assets/deborah_ufw/new-pause-button.svg b/third_party/example/assets/deborah_ufw/new-pause-button.svg new file mode 100644 index 000000000000..90deeee9a5af --- /dev/null +++ b/third_party/example/assets/deborah_ufw/new-pause-button.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + diff --git a/third_party/example/assets/deborah_ufw/new-play-button.svg b/third_party/example/assets/deborah_ufw/new-play-button.svg new file mode 100644 index 000000000000..40799c91370e --- /dev/null +++ b/third_party/example/assets/deborah_ufw/new-play-button.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + diff --git a/third_party/example/assets/deborah_ufw/new-send-circle.svg b/third_party/example/assets/deborah_ufw/new-send-circle.svg new file mode 100644 index 000000000000..ab58e6b145fd --- /dev/null +++ b/third_party/example/assets/deborah_ufw/new-send-circle.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + diff --git a/third_party/example/assets/deborah_ufw/numeric_25.svg b/third_party/example/assets/deborah_ufw/numeric_25.svg new file mode 100644 index 000000000000..ea6f38c2b3d8 --- /dev/null +++ b/third_party/example/assets/deborah_ufw/numeric_25.svg @@ -0,0 +1,19 @@ + + + +icon-font/25/numeric_25 +Created with Sketch. + + + + diff --git a/third_party/example/assets/flutter_logo.svg b/third_party/example/assets/flutter_logo.svg new file mode 100644 index 000000000000..ec3d9144f352 --- /dev/null +++ b/third_party/example/assets/flutter_logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/clip_path.svg b/third_party/example/assets/simple/clip_path.svg new file mode 100644 index 000000000000..d0877e91a4ff --- /dev/null +++ b/third_party/example/assets/simple/clip_path.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/third_party/example/assets/simple/clip_path_2.svg b/third_party/example/assets/simple/clip_path_2.svg new file mode 100644 index 000000000000..a9707d923da3 --- /dev/null +++ b/third_party/example/assets/simple/clip_path_2.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/clip_path_3.svg b/third_party/example/assets/simple/clip_path_3.svg new file mode 100644 index 000000000000..aae181a1e7dc --- /dev/null +++ b/third_party/example/assets/simple/clip_path_3.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/third_party/example/assets/simple/dash_path.svg b/third_party/example/assets/simple/dash_path.svg new file mode 100644 index 000000000000..cbd5fa9a4b85 --- /dev/null +++ b/third_party/example/assets/simple/dash_path.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/ellipse.svg b/third_party/example/assets/simple/ellipse.svg new file mode 100644 index 000000000000..2ea45661cf0d --- /dev/null +++ b/third_party/example/assets/simple/ellipse.svg @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/group_fill_opacity.svg b/third_party/example/assets/simple/group_fill_opacity.svg new file mode 100644 index 000000000000..7a8e04f6604c --- /dev/null +++ b/third_party/example/assets/simple/group_fill_opacity.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/group_opacity.svg b/third_party/example/assets/simple/group_opacity.svg new file mode 100644 index 000000000000..1bc0a7a7f548 --- /dev/null +++ b/third_party/example/assets/simple/group_opacity.svg @@ -0,0 +1,46 @@ + + + + Example opacity01 - opacity property + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/example/assets/simple/linear_gradient.svg b/third_party/example/assets/simple/linear_gradient.svg new file mode 100644 index 000000000000..c0d45cdc5094 --- /dev/null +++ b/third_party/example/assets/simple/linear_gradient.svg @@ -0,0 +1,11 @@ + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/linear_gradient_2.svg b/third_party/example/assets/simple/linear_gradient_2.svg new file mode 100644 index 000000000000..eb75d36c2646 --- /dev/null +++ b/third_party/example/assets/simple/linear_gradient_2.svg @@ -0,0 +1,24 @@ + + + + Example lingrad01 - fill a rectangle using a + linear gradient paint server + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/linear_gradient_absolute_user_space_translate.svg b/third_party/example/assets/simple/linear_gradient_absolute_user_space_translate.svg new file mode 100644 index 000000000000..ced5251b3e65 --- /dev/null +++ b/third_party/example/assets/simple/linear_gradient_absolute_user_space_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/example/assets/simple/linear_gradient_percentage_bounding_translate.svg b/third_party/example/assets/simple/linear_gradient_percentage_bounding_translate.svg new file mode 100644 index 000000000000..be1ef28c5502 --- /dev/null +++ b/third_party/example/assets/simple/linear_gradient_percentage_bounding_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/example/assets/simple/linear_gradient_percentage_user_space_translate.svg b/third_party/example/assets/simple/linear_gradient_percentage_user_space_translate.svg new file mode 100644 index 000000000000..c2b0ce07ffb1 --- /dev/null +++ b/third_party/example/assets/simple/linear_gradient_percentage_user_space_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/example/assets/simple/nested_group.svg b/third_party/example/assets/simple/nested_group.svg new file mode 100644 index 000000000000..6f8472319a67 --- /dev/null +++ b/third_party/example/assets/simple/nested_group.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/opacity_on_path.svg b/third_party/example/assets/simple/opacity_on_path.svg new file mode 100644 index 000000000000..9f870d066e21 --- /dev/null +++ b/third_party/example/assets/simple/opacity_on_path.svg @@ -0,0 +1,3 @@ + + + diff --git a/third_party/example/assets/simple/radial_gradient.svg b/third_party/example/assets/simple/radial_gradient.svg new file mode 100644 index 000000000000..42bcbd6e9038 --- /dev/null +++ b/third_party/example/assets/simple/radial_gradient.svg @@ -0,0 +1,26 @@ + + + + Example radgrad01 - fill a rectangle by referencing a + radial gradient paint server + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/radial_gradient_absolute_user_space_translate.svg b/third_party/example/assets/simple/radial_gradient_absolute_user_space_translate.svg new file mode 100644 index 000000000000..4268fea810d2 --- /dev/null +++ b/third_party/example/assets/simple/radial_gradient_absolute_user_space_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/example/assets/simple/radial_gradient_focal.svg b/third_party/example/assets/simple/radial_gradient_focal.svg new file mode 100644 index 000000000000..862c829f50b3 --- /dev/null +++ b/third_party/example/assets/simple/radial_gradient_focal.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/radial_gradient_percentage_bounding_translate.svg b/third_party/example/assets/simple/radial_gradient_percentage_bounding_translate.svg new file mode 100644 index 000000000000..3fd58495c8b6 --- /dev/null +++ b/third_party/example/assets/simple/radial_gradient_percentage_bounding_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/example/assets/simple/radial_gradient_percentage_user_space_translate.svg b/third_party/example/assets/simple/radial_gradient_percentage_user_space_translate.svg new file mode 100644 index 000000000000..303ff7d27ae3 --- /dev/null +++ b/third_party/example/assets/simple/radial_gradient_percentage_user_space_translate.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/third_party/example/assets/simple/rect_rrect.svg b/third_party/example/assets/simple/rect_rrect.svg new file mode 100644 index 000000000000..5960d185df26 --- /dev/null +++ b/third_party/example/assets/simple/rect_rrect.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/third_party/example/assets/simple/rect_rrect_no_ry.svg b/third_party/example/assets/simple/rect_rrect_no_ry.svg new file mode 100644 index 000000000000..b98dd11995ca --- /dev/null +++ b/third_party/example/assets/simple/rect_rrect_no_ry.svg @@ -0,0 +1,3 @@ + + + diff --git a/third_party/example/assets/simple/style_attr.svg b/third_party/example/assets/simple/style_attr.svg new file mode 100644 index 000000000000..1c42fd79dd0f --- /dev/null +++ b/third_party/example/assets/simple/style_attr.svg @@ -0,0 +1,6 @@ + + + diff --git a/third_party/example/assets/simple/text.svg b/third_party/example/assets/simple/text.svg new file mode 100644 index 000000000000..ac5bb68b079a --- /dev/null +++ b/third_party/example/assets/simple/text.svg @@ -0,0 +1,16 @@ + + + + Example text01 - 'Hello, out there' in blue + + + Hello, out there + + + + + \ No newline at end of file diff --git a/third_party/example/assets/w3samples/aa.svg b/third_party/example/assets/w3samples/aa.svg new file mode 100644 index 000000000000..2f2d26b165a7 --- /dev/null +++ b/third_party/example/assets/w3samples/aa.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/third_party/example/assets/w3samples/alphachannel.svg b/third_party/example/assets/w3samples/alphachannel.svg new file mode 100644 index 000000000000..be7bf45d07ee --- /dev/null +++ b/third_party/example/assets/w3samples/alphachannel.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/third_party/example/assets/wikimedia/Firefox_Logo_2017.svg b/third_party/example/assets/wikimedia/Firefox_Logo_2017.svg new file mode 100644 index 000000000000..87caae6a7913 --- /dev/null +++ b/third_party/example/assets/wikimedia/Firefox_Logo_2017.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + firefox-logo + + + + + + + + + + + + + + + + + diff --git a/third_party/example/assets/wikimedia/Ghostscript_Tiger.svg b/third_party/example/assets/wikimedia/Ghostscript_Tiger.svg new file mode 100644 index 000000000000..679edec2eb3f --- /dev/null +++ b/third_party/example/assets/wikimedia/Ghostscript_Tiger.svg @@ -0,0 +1,725 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/example/assets/wikimedia/chess_knight.svg b/third_party/example/assets/wikimedia/chess_knight.svg new file mode 100644 index 000000000000..eabd2af51a23 --- /dev/null +++ b/third_party/example/assets/wikimedia/chess_knight.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + diff --git a/third_party/example/example.iml b/third_party/example/example.iml new file mode 100644 index 000000000000..e5c837191e06 --- /dev/null +++ b/third_party/example/example.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/example_android.iml b/third_party/example/example_android.iml new file mode 100644 index 000000000000..b050030a1b87 --- /dev/null +++ b/third_party/example/example_android.iml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + diff --git a/third_party/example/ios/.gitignore b/third_party/example/ios/.gitignore new file mode 100644 index 000000000000..79cc4da802e9 --- /dev/null +++ b/third_party/example/ios/.gitignore @@ -0,0 +1,45 @@ +.idea/ +.vagrant/ +.sconsign.dblite +.svn/ + +.DS_Store +*.swp +profile + +DerivedData/ +build/ +GeneratedPluginRegistrant.h +GeneratedPluginRegistrant.m + +.generated/ + +*.pbxuser +*.mode1v3 +*.mode2v3 +*.perspectivev3 + +!default.pbxuser +!default.mode1v3 +!default.mode2v3 +!default.perspectivev3 + +xcuserdata + +*.moved-aside + +*.pyc +*sync/ +Icon? +.tags* + +/Flutter/app.flx +/Flutter/app.zip +/Flutter/flutter_assets/ +/Flutter/App.framework +/Flutter/Flutter.framework +/Flutter/Generated.xcconfig +/ServiceDefinitions.json + +Pods/ +.symlinks/ diff --git a/third_party/example/ios/Flutter/AppFrameworkInfo.plist b/third_party/example/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 000000000000..9367d483e44e --- /dev/null +++ b/third_party/example/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 8.0 + + diff --git a/third_party/example/ios/Flutter/Debug.xcconfig b/third_party/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000000..592ceee85b89 --- /dev/null +++ b/third_party/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/third_party/example/ios/Flutter/Release.xcconfig b/third_party/example/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000000..592ceee85b89 --- /dev/null +++ b/third_party/example/ios/Flutter/Release.xcconfig @@ -0,0 +1 @@ +#include "Generated.xcconfig" diff --git a/third_party/example/ios/Runner.xcodeproj/project.pbxproj b/third_party/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000000..bdbe25e77640 --- /dev/null +++ b/third_party/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,436 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; + 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, + 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, + 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 2D5378251FAA1A9400D5DBA9 /* flutter_assets */, + 3B80C3931E831B6300D905FE /* App.framework */, + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEBA1CF902C7004384FC /* Flutter.framework */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, + 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 97C146F11CF9000F007C117D /* Supporting Files */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + ); + path = Runner; + sourceTree = ""; + }; + 97C146F11CF9000F007C117D /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 97C146F21CF9000F007C117D /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0910; + ORGANIZATIONNAME = "The Chromium Authors"; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, + 97C146F31CF9000F007C117D /* main.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/third_party/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/third_party/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..1d526a16ed0f --- /dev/null +++ b/third_party/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/third_party/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/third_party/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 000000000000..1263ac84b105 --- /dev/null +++ b/third_party/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/third_party/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000000..1d526a16ed0f --- /dev/null +++ b/third_party/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/third_party/example/ios/Runner/AppDelegate.h b/third_party/example/ios/Runner/AppDelegate.h new file mode 100644 index 000000000000..36e21bbf9cf4 --- /dev/null +++ b/third_party/example/ios/Runner/AppDelegate.h @@ -0,0 +1,6 @@ +#import +#import + +@interface AppDelegate : FlutterAppDelegate + +@end diff --git a/third_party/example/ios/Runner/AppDelegate.m b/third_party/example/ios/Runner/AppDelegate.m new file mode 100644 index 000000000000..59a72e90be12 --- /dev/null +++ b/third_party/example/ios/Runner/AppDelegate.m @@ -0,0 +1,13 @@ +#include "AppDelegate.h" +#include "GeneratedPluginRegistrant.h" + +@implementation AppDelegate + +- (BOOL)application:(UIApplication *)application + didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + [GeneratedPluginRegistrant registerWithRegistry:self]; + // Override point for customization after application launch. + return [super application:application didFinishLaunchingWithOptions:launchOptions]; +} + +@end diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 000000000000..d36b1fab2d9d --- /dev/null +++ b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d43d11e66f4de3da27ed045ca4fe38ad8b48094 GIT binary patch literal 11112 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 P-1+_A+?hGkL;m(J7kc&K literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..28c6bf03016f6c994b70f38d1b7346e5831b531f GIT binary patch literal 564 zcmV-40?Yl0P)Px$?ny*JR5%f>l)FnDQ543{x%ZCiu33$Wg!pQFfT_}?5Q|_VSlIbLC`dpoMXL}9 zHfd9&47Mo(7D231gb+kjFxZHS4-m~7WurTH&doVX2KI5sU4v(sJ1@T9eCIKPjsqSr z)C01LsCxk=72-vXmX}CQD#BD;Cthymh&~=f$Q8nn0J<}ZrusBy4PvRNE}+1ceuj8u z0mW5k8fmgeLnTbWHGwfKA3@PdZxhn|PypR&^p?weGftrtCbjF#+zk_5BJh7;0`#Wr zgDpM_;Ax{jO##IrT`Oz;MvfwGfV$zD#c2xckpcXC6oou4ML~ezCc2EtnsQTB4tWNg z?4bkf;hG7IMfhgNI(FV5Gs4|*GyMTIY0$B=_*mso9Ityq$m^S>15>-?0(zQ<8Qy<_TjHE33(?_M8oaM zyc;NxzRVK@DL6RJnX%U^xW0Gpg(lXp(!uK1v0YgHjs^ZXSQ|m#lV7ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f091b6b0bca859a3f474b03065bef75ba58a9e4c GIT binary patch literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ef06e7edb86cdfe0d15b4b0d98334a86163658 GIT binary patch literal 1716 zcmds$`#;kQ7{|XelZftyR5~xW7?MLxS4^|Hw3&P7^y)@A9Fj{Xm1~_CIV^XZ%SLBn zA;!r`GqGHg=7>xrB{?psZQs88ZaedDoagm^KF{a*>G|dJWRSe^I$DNW008I^+;Kjt z>9p3GNR^I;v>5_`+91i(*G;u5|L+Bu6M=(afLjtkya#yZ175|z$pU~>2#^Z_pCZ7o z1c6UNcv2B3?; zX%qdxCXQpdKRz=#b*q0P%b&o)5ZrNZt7$fiETSK_VaY=mb4GK`#~0K#~9^ zcY!`#Af+4h?UMR-gMKOmpuYeN5P*RKF!(tb`)oe0j2BH1l?=>y#S5pMqkx6i{*=V9JF%>N8`ewGhRE(|WohnD59R^$_36{4>S zDFlPC5|k?;SPsDo87!B{6*7eqmMdU|QZ84>6)Kd9wNfh90=y=TFQay-0__>=<4pk& zYDjgIhL-jQ9o>z32K)BgAH+HxamL{ZL~ozu)Qqe@a`FpH=oQRA8=L-m-1dam(Ix2V z?du;LdMO+ooBelr^_y4{|44tmgH^2hSzPFd;U^!1p>6d|o)(-01z{i&Kj@)z-yfWQ)V#3Uo!_U}q3u`(fOs`_f^ueFii1xBNUB z6MecwJN$CqV&vhc+)b(p4NzGGEgwWNs z@*lUV6LaduZH)4_g!cE<2G6#+hJrWd5(|p1Z;YJ7ifVHv+n49btR}dq?HHDjl{m$T z!jLZcGkb&XS2OG~u%&R$(X+Z`CWec%QKt>NGYvd5g20)PU(dOn^7%@6kQb}C(%=vr z{?RP(z~C9DPnL{q^@pVw@|Vx~@3v!9dCaBtbh2EdtoNHm4kGxp>i#ct)7p|$QJs+U z-a3qtcPvhihub?wnJqEt>zC@)2suY?%-96cYCm$Q8R%-8$PZYsx3~QOLMDf(piXMm zB=<63yQk1AdOz#-qsEDX>>c)EES%$owHKue;?B3)8aRd}m~_)>SL3h2(9X;|+2#7X z+#2)NpD%qJvCQ0a-uzZLmz*ms+l*N}w)3LRQ*6>|Ub-fyptY(keUxw+)jfwF5K{L9 z|Cl_w=`!l_o><384d&?)$6Nh(GAm=4p_;{qVn#hI8lqewW7~wUlyBM-4Z|)cZr?Rh z=xZ&Ol>4(CU85ea(CZ^aO@2N18K>ftl8>2MqetAR53_JA>Fal`^)1Y--Am~UDa4th zKfCYpcXky$XSFDWBMIl(q=Mxj$iMBX=|j9P)^fDmF(5(5$|?Cx}DKEJa&XZP%OyE`*GvvYQ4PV&!g2|L^Q z?YG}tx;sY@GzMmsY`7r$P+F_YLz)(e}% zyakqFB<6|x9R#TdoP{R$>o7y(-`$$p0NxJ6?2B8tH)4^yF(WhqGZlM3=9Ibs$%U1w zWzcss*_c0=v_+^bfb`kBFsI`d;ElwiU%frgRB%qBjn@!0U2zZehBn|{%uNIKBA7n= zzE`nnwTP85{g;8AkYxA68>#muXa!G>xH22D1I*SiD~7C?7Za+9y7j1SHiuSkKK*^O zsZ==KO(Ua#?YUpXl{ViynyT#Hzk=}5X$e04O@fsMQjb}EMuPWFO0e&8(2N(29$@Vd zn1h8Yd>6z(*p^E{c(L0Lg=wVdupg!z@WG;E0k|4a%s7Up5C0c)55XVK*|x9RQeZ1J@1v9MX;>n34(i>=YE@Iur`0Vah(inE3VUFZNqf~tSz{1fz3Fsn_x4F>o(Yo;kpqvBe-sbwH(*Y zu$JOl0b83zu$JMvy<#oH^Wl>aWL*?aDwnS0iEAwC?DK@aT)GHRLhnz2WCvf3Ba;o=aY7 z2{Asu5MEjGOY4O#Ggz@@J;q*0`kd2n8I3BeNuMmYZf{}pg=jTdTCrIIYuW~luKecn z+E-pHY%ohj@uS0%^ z&(OxwPFPD$+#~`H?fMvi9geVLci(`K?Kj|w{rZ9JgthFHV+=6vMbK~0)Ea<&WY-NC zy-PnZft_k2tfeQ*SuC=nUj4H%SQ&Y$gbH4#2sT0cU0SdFs=*W*4hKGpuR1{)mV;Qf5pw4? zfiQgy0w3fC*w&Bj#{&=7033qFR*<*61B4f9K%CQvxEn&bsWJ{&winp;FP!KBj=(P6 z4Z_n4L7cS;ao2)ax?Tm|I1pH|uLpDSRVghkA_UtFFuZ0b2#>!8;>-_0ELjQSD-DRd z4im;599VHDZYtnWZGAB25W-e(2VrzEh|etsv2YoP#VbIZ{aFkwPrzJ#JvCvA*mXS& z`}Q^v9(W4GiSs}#s7BaN!WA2bniM$0J(#;MR>uIJ^uvgD3GS^%*ikdW6-!VFUU?JV zZc2)4cMsX@j z5HQ^e3BUzOdm}yC-xA%SY``k$rbfk z;CHqifhU*jfGM@DkYCecD9vl*qr58l6x<8URB=&%{!Cu3RO*MrKZ4VO}V6R0a zZw3Eg^0iKWM1dcTYZ0>N899=r6?+adUiBKPciJw}L$=1f4cs^bio&cr9baLF>6#BM z(F}EXe-`F=f_@`A7+Q&|QaZ??Txp_dB#lg!NH=t3$G8&06MFhwR=Iu*Im0s_b2B@| znW>X}sy~m#EW)&6E&!*0%}8UAS)wjt+A(io#wGI@Z2S+Ms1Cxl%YVE800007ip7{`C_J2TxPmfw%h$|%acrYHt)Re^PB%O&&=~a zhS(%I#+V>J-vjIib^<+s%ludY7y^C(P8nmqn9fp!i+?vr`bziDE=bx`%2W#Xyrj|i z!XQ4v1%L`m{7KT7q+LZNB^h8Ha2e=`Wp65^0;J00)_^G=au=8Yo;1b`CV&@#=jIBo zjN^JNVfYSs)+kDdGe7`1&8!?MQYKS?DuHZf3iogk_%#9E|5S zWeHrmAo>P;ejX7mwq#*}W25m^ZI+{(Z8fI?4jM_fffY0nok=+88^|*_DwcW>mR#e+ zX$F_KMdb6sRz!~7KkyN0G(3XQ+;z3X%PZ4gh;n-%62U<*VUKNv(D&Q->Na@Xb&u5Q3`3DGf+a8O5x7c#7+R+EAYl@R5us)CIw z7sT@_y~Ao@uL#&^LIh&QceqiT^+lb0YbFZt_SHOtWA%mgPEKVNvVgCsXy{5+zl*X8 zCJe)Q@y>wH^>l4;h1l^Y*9%-23TSmE>q5nI@?mt%n;Sj4Qq`Z+ib)a*a^cJc%E9^J zB;4s+K@rARbcBLT5P=@r;IVnBMKvT*)ew*R;&8vu%?Z&S>s?8?)3*YawM0P4!q$Kv zMmKh3lgE~&w&v%wVzH3Oe=jeNT=n@Y6J6TdHWTjXfX~-=1A1Bw`EW8rn}MqeI34nh zexFeA?&C3B2(E?0{drE@DA2pu(A#ElY&6el60Rn|Qpn-FkfQ8M93AfWIr)drgDFEU zghdWK)^71EWCP(@(=c4kfH1Y(4iugD4fve6;nSUpLT%!)MUHs1!zJYy4y||C+SwQ! z)KM&$7_tyM`sljP2fz6&Z;jxRn{Wup8IOUx8D4uh&(=O zx-7$a;U><*5L^!%xRlw)vAbh;sdlR||& ze}8_8%)c2Fwy=F&H|LM+p{pZB5DKTx>Y?F1N%BlZkXf!}JeGuMZk~LPi7{cidvUGB zAJ4LVeNV%XO>LTrklB#^-;8nb;}6l;1oW&WS=Mz*Az!4cqqQzbOSFq`$Q%PfD7srM zpKgP-D_0XPTRX*hAqeq0TDkJ;5HB1%$3Np)99#16c{ zJImlNL(npL!W|Gr_kxl1GVmF5&^$^YherS7+~q$p zt}{a=*RiD2Ikv6o=IM1kgc7zqpaZ;OB)P!1zz*i3{U()Dq#jG)egvK}@uFLa`oyWZ zf~=MV)|yJn`M^$N%ul5);JuQvaU1r2wt(}J_Qgyy`qWQI`hEeRX0uC@c1(dQ2}=U$ tNIIaX+dr)NRWXcxoR{>fqI{SF_dm1Ylv~=3YHI)h002ovPDHLkV1g(pWS;;4 literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f9ed8f5cee1c98386d13b17e89f719e83555b2 GIT binary patch literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..75b2d164a5a98e212cca15ea7bf2ab5de5108680 GIT binary patch literal 3831 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 literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c4df70d39da7941ef3f6dcb7f06a192d8dcb308d GIT binary patch literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 000000000000..89c2725b70f1 --- /dev/null +++ b/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/third_party/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/third_party/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 000000000000..f2e259c7c939 --- /dev/null +++ b/third_party/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/example/ios/Runner/Base.lproj/Main.storyboard b/third_party/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 000000000000..f3c28516fb38 --- /dev/null +++ b/third_party/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/example/ios/Runner/Info.plist b/third_party/example/ios/Runner/Info.plist new file mode 100644 index 000000000000..0513117f1d0b --- /dev/null +++ b/third_party/example/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/third_party/example/ios/Runner/main.m b/third_party/example/ios/Runner/main.m new file mode 100644 index 000000000000..dff6597e4513 --- /dev/null +++ b/third_party/example/ios/Runner/main.m @@ -0,0 +1,9 @@ +#import +#import +#import "AppDelegate.h" + +int main(int argc, char* argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart new file mode 100644 index 000000000000..c8fec93b7b54 --- /dev/null +++ b/third_party/example/lib/main.dart @@ -0,0 +1,169 @@ +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter_svg/avd.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +const List assetNames = const [ + // 'assets/notfound.svg', + 'assets/flutter_logo.svg', + 'assets/dart.svg', + 'assets/simple/clip_path_3.svg', + 'assets/simple/clip_path_2.svg', + 'assets/simple/clip_path.svg', + 'assets/simple/group_fill_opacity.svg', + 'assets/simple/group_opacity.svg', + 'assets/simple/text.svg', + 'assets/simple/linear_gradient.svg', + 'assets/simple/linear_gradient_2.svg', + 'assets/simple/radial_gradient.svg', + 'assets/simple/rect_rrect.svg', + 'assets/simple/rect_rrect_no_ry.svg', + 'assets/simple/style_attr.svg', + 'assets/w3samples/aa.svg', + 'assets/w3samples/alphachannel.svg', + 'assets/simple/ellipse.svg', + 'assets/simple/dash_path.svg', + 'assets/simple/nested_group.svg', + 'assets/wikimedia/chess_knight.svg', + 'assets/wikimedia/Ghostscript_Tiger.svg', + 'assets/wikimedia/Firefox_Logo_2017.svg', +]; + +const List iconNames = const [ + 'assets/deborah_ufw/new-action-expander.svg', + 'assets/deborah_ufw/new-camera.svg', + 'assets/deborah_ufw/new-gif-button.svg', + 'assets/deborah_ufw/new-gif.svg', + 'assets/deborah_ufw/new-image.svg', + 'assets/deborah_ufw/new-mention.svg', + 'assets/deborah_ufw/new-pause-button.svg', + 'assets/deborah_ufw/new-play-button.svg', + 'assets/deborah_ufw/new-send-circle.svg', + 'assets/deborah_ufw/numeric_25.svg', +]; + +const List uriNames = const [ + 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', + 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', +]; + +void main() { + runApp(new MyApp()); +} + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return new MaterialApp( + title: 'Flutter Demo', + theme: new ThemeData( + primarySwatch: Colors.blue, + ), + home: const MyHomePage(title: 'Flutter SVG Demo'), + ); + } +} + +class MyHomePage extends StatefulWidget { + const MyHomePage({Key key, this.title}) : super(key: key); + final String title; + + @override + _MyHomePageState createState() => new _MyHomePageState(); +} + +class _MyHomePageState extends State { + final List _painters = []; + double _dimension; + + @override + void initState() { + super.initState(); + _dimension = 250.0; + + _painters.add(new SvgPicture.string( + ''' + + + + + + +''')); + + for (String assetName in assetNames) { + _painters.add( + new SvgPicture.asset(assetName), + ); + } + + for (int i = 0; i < iconNames.length; i++) { + _painters.add( + new Directionality( + textDirection: TextDirection.ltr, + child: new SvgPicture.asset( + iconNames[i], + color: Colors.blueGrey[(i + 1) * 100], + matchTextDirection: true, + ), + ), + ); + } + + // _painters.add(new SvgPicture.asset(iconNames[0], color: Colors.red)); + + for (String uriName in uriNames) { + _painters.add( + new SvgPicture.network( + uriName, + placeholderBuilder: (BuildContext context) => new Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator()), + ), + ); + } + _painters + .add(new AvdPicture.asset('assets/android_vd/battery_charging.xml')); + } + + @override + Widget build(BuildContext context) { + if (_dimension > MediaQuery.of(context).size.width - 10.0) { + _dimension = MediaQuery.of(context).size.width - 10.0; + } + return new Scaffold( + appBar: new AppBar( + title: new Text(widget.title), + ), + body: new Column(children: [ + new Slider( + min: 5.0, + max: MediaQuery.of(context).size.width - 10.0, + value: _dimension, + onChanged: (double val) { + setState(() => _dimension = val); + }), + // new FlutterLogo(size: _dimension), + // new Container( + // padding: const EdgeInsets.all(12.0), + // child: + + // ) + new Expanded( + child: new GridView.extent( + shrinkWrap: true, + maxCrossAxisExtent: _dimension, + padding: const EdgeInsets.all(4.0), + mainAxisSpacing: 4.0, + crossAxisSpacing: 4.0, + children: _painters.toList(), + ), + ), + ]), + ); + } +} \ No newline at end of file diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock new file mode 100644 index 000000000000..64dfff14e174 --- /dev/null +++ b/third_party/example/pubspec.lock @@ -0,0 +1,79 @@ +# Generated by pub +# See https://www.dartlang.org/tools/pub/glossary#lockfile +packages: + collection: + dependency: transitive + description: + name: collection + url: "https://pub.dartlang.org" + source: hosted + version: "1.14.11" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_svg: + dependency: "direct main" + description: + path: ".." + relative: true + source: path + version: "0.5.5+1" + meta: + dependency: transitive + description: + name: meta + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + path_drawing: + dependency: transitive + description: + name: path_drawing + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" + path_parsing: + dependency: transitive + description: + name: path_parsing + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.2" + petitparser: + dependency: transitive + description: + name: petitparser + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + typed_data: + dependency: transitive + description: + name: typed_data + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.6" + vector_math: + dependency: transitive + description: + name: vector_math + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + xml: + dependency: transitive + description: + name: xml + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" +sdks: + dart: ">=2.0.0-dev.69.0 <3.0.0" + flutter: ">=0.7.3 <2.0.0" diff --git a/third_party/example/pubspec.yaml b/third_party/example/pubspec.yaml new file mode 100644 index 000000000000..5481ef57bd25 --- /dev/null +++ b/third_party/example/pubspec.yaml @@ -0,0 +1,41 @@ +name: flutter_svg_example +description: An SVG samnple app. +author: Dan Field +homepage: https://github.com/dnfield/flutter_svg +version: 0.0.1 + +dependencies: + flutter_svg: + path: ../ + flutter: + sdk: flutter + +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/ + - assets/w3samples/ + - assets/deborah_ufw/ + - assets/simple/ + - assets/wikimedia/ + - assets/android_vd/ + +environment: + sdk: ">=1.19.0 <3.0.0" + flutter: ">=0.7.3 <2.0.0" + +# dependency_overrides: +# sky_engine: +# path: /Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_engine +# sky_services: +# path: /Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_services diff --git a/third_party/golden/wikimedia/Firefox_Logo_2017.png b/third_party/golden/wikimedia/Firefox_Logo_2017.png new file mode 100644 index 0000000000000000000000000000000000000000..0cd76b9f0433fee3cb94291410be9613dbd146fc GIT binary patch literal 24368 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 WR$SYwx&+a2QJEN+>sRPHNBkf2wlw(w literal 44529 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

lP{oi7W4 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 literal 9850 zcmcIqi(gDz^glC=I*2(_9(gs7^gvYPRkvvxlU{nDzu>={r-VpAD@qP_Fn6|ziX|%_gQbD3*tTV0TSvEbP` zt9UeZ+m`^L}3-?nY*HalPxT0FXS zYftK@^WRKA4T>{P1@7-Y|NY$3%JjU{y<6ANf#3huCzF{CnQz9_vJxq#6iPnRZIDMZPg1kSj;9Tmkk<*UurPBoj<80l+ z&SduY;kyR>#=hBAOTp)SlIi+G2#rI=L}{J2071!^;4{Ie3uH{8y?b@lGbm?E;m@iDF(%V1ttnjx9O*qqf>l_7Na0pEf=H3oUkM^kD(HhQLzhSy@)TT%Ad^$_6i>0}7-VX!YF`_rb;8EGp>sH&MXdKHU|hIb-D zYoiDl1FZteo41fIH*)kUd6`ok*j{MUl>w!hBdrkqu&?CDByB4vn5qC!wTvIHFJP8pxlp!`V@) z3Q#>r5nzKzr$loQ&r_nuN_QqwrP3T3mkqH-h9J=I4=FeqbIs(#;~PhI%W1vGH{>G@ z96s6}A|8%qA9%LEE*;Ug#gUn?wVhNzl0k&64Mb&_*Y8(Sq7Xz8C5mulqb?tXj45de zkdq3Io}8u{htQ&bHfjs-i&0FW8oLA^i>0jxE~P4l{&a>OsLqztCIRY07Fzw`3ZXMJH02i7 z%}N~EYyloY;v<_te1H){A--GzZb6CN90A^-PPWE?!ls`h&~8v8TOEj2O6-Qf6l;-# zRak<^qeOW96mv;YAEHqV(S&H|1F?T8Hg+ryu~~!TCDjZRgVzfX&sU?-feN8|l~5&p zM1Dsx&LoQY4Ctp&y?_i>s=|$8;-494)pD{wjYVg)C6G{68Z>$Ul^O2@gl0ln8AIxF zC~w@r-E|a~9N@Bp!deIUm`u_VbOP)$3Ra!Y@cs!qjYc=7VA}w8It3d5ux}_VE|8r^ zkyWM9y{N!QcmiCX8o-}{<}alBXVd6csR@I^RJNmN2_a!?DAg~Z3R@FoENv=?uz(10 zDP(*pCAxw*l@bFPsJ|=4+h8o#B%(w=5UJTE$OF-uYV84WA}N+|P^@VRC3=ErNr`FT zgACGOD@Igf5E{8|a0@k#6BQ26dO z5IZs8m)L^{dmAC{0ugo=LS!+}-t&}b1mYP=919|q#S(WEYvWR2%R!v>Q#^i06FHNr z;9T@c<{R*lGpE(DHh8m(YD^A?H$*T-%H*lB z5o3E?phBU(Y;Pz=9+bypL)s7^%iYjEe0!tlAZeT|(V6VGIIhM2mvv!j`ZpNvJ%llbLO`#sa= z^S|YOiw!gzZ)}N|7!e#}#ic4Qq)c0`pa~^>vf?*KdY7tbvpD`xYl)h**m4Ww=E!Ok zyG=&&M67}{U2YM@Kw-m&)U?9eccs{AE{#sUnTTPIE7H8^lIAEPM}t!4MHV~30e3R~ zUo<5K3Uv*^8nUm&Z;C@Mz)JmZY^XN$pd#kUsj+B~k;vu;QKh>FnOZ zyP9LRma0^gjYWyV-&*Xo$Be(SITC7%3cr_q2%?R#lcY?#8arP@m!q1v7Q6Ug!!p|6 zX;Ii69sWWVn*n9pa)Jprz*6i5F9~ZgQNvhb+yeVw&)XU3LwNqLzXSSNT;pH;0!;{` z6g$iNi3f#^@Pr60ii%xTszQrmmfPV@`YhpsW-WEOg`ipKt2$?ry(E9G`~;+mBd0xs z*NCGeU;n>n7AH=G9##Lzze=A*uZzMyYX5{!3r^2f!SzO3t(N2+V@?b+mUTSN-Ns$; z%e>2)f2~10J@0Gw!AwT3>1fYXR1FffZiD5}}3vp)a7(%P?+*^e0*GR3t)O ziv3a#Sb>+gOXK$Z@}(^XiC8X;`}#{A>ZXY0QE_|zdrm-Op4C!coi{N29EMJ>Q3CDH^rn*YhYm$D!>h|Jkc? zstj4xvwj8lhqfSX3@_uruUrnn_;w=e&|l;CLinac#eMu0FAZfHeZD&P*)M+$XA;S) z7LU|VO>N8#4AUo*H|?ZJZTM_HRF%YZT+cuQ1d>*l%%Rv#yF1=jN@Ht_Kct(62Rgej z17LrVGBw~lJd4E*u4rxvZ1~;&PKvBYQylbN#j0lLL_)_86PLIrZ;e5vYP`43wcIjM3$POcu9bu`J!<9#6$58H6IccMQ# z)H4D#eo@QjmBbpNZBge`scTzG73G;(iZd*(K2!^IMo5MPWw8g1XAzdcQB00Djb6N{ zm1rv<(eAR?CC315`kxYMtoUsVQ2Tp#sfzz18r^Jh2B8-~>b;9%Hth$zohZSi-Gp!p z-lxl=k%*Mey@c(>QXp(0M#@+mL*&3QOn$<#fFSY#%4!>^1w^Slk+@ZTF<4p$!w5@Z zMj&4m#I?YE_nzVP+12Xqm3!2{tXE+@N0y!4u&K7s7lK}Qqv|&~tpZjgPR^h3kwbo? zK`#kzy<7rq8dU2Bg`N+P;=v2sp8NX#)oPaI;MWn7I1Rv3Awj-n(-+8T`a--!U>Qvi z^B|(88mmC25LFIOL`1EJNWtM1aH_*NhW_p=p>3NU(Kh4=ZBT9D3kU}mkxu>4=Ho6< zR*B9L;h44^=1$xQgfbgSsf^1fTj$9kAGPBQ~pAQ%)&gba|mM1 zn~iuG!OcqEaO2YL{}XJF$a*h;!3l3>`$xhhSdh}VVQ5+cO`Xq}W_$NRaMaNL=r6amro|jFtQri=^IweFkS>Y{k zDZY^1X`Xi_JNxsN@!-g5{kI6zI}_Bnb}Y7_PX9GBfyJJWamT|GW6BO(SsDv_3|xV5 z#*JSr*xH<~#A}7xMOw<65O+e+7Kbi}y7b~TffBsW=oq&UV+%wN4W1**rLh8$wJn@t zc2B-*sMHF*bAJ<-s$jqGKDtog(5#g&)Dnr27n5&rlv;K8A!+&Gt$?i>W~A(WP|a9(kAO9Z3|$^LY9N?V zT8696hLNgVi`|20Z+U#>%by^3IKQ+0;`k~Zxsj*YaSTql?tW7?;Am`(ZOHg{ z>IQs)H1=RGVQe_*kEw2Wt~8cDCKi-cZEjmmNwaHC_p~5buTb9_F{TX;nr;#)(^G2V zv605Z*njC+6OWe}sMBxq2eV9K2*V^e@#^rGt+OI1Tu|o_SCfIYdq6RbK^}HJediP8 zq1wWmrOYX>{E4pF&=sxl^qD|*!BO{5DRW)oavfGR_pUfej0N{Mo^a)N{H`W9EBn=2+w{Bl?m2{J*_tol<0tD6Tw@T$|BmdA92fVV zO9?u<_i`OV<3ql#ZC28AuZ5ZhF2GDy*QMrM=~!jb(S5K}E`P&r7;foTQIf(DHDeDPBqnZ(VxDj$z3{ScTc*q6vktnWP^!OwvZAeo-GxV9rO5o-%}M|$5)EG+zm!&^bD>V zig2v2>05=IAO_%nd)~4AK*wh$ygZy8nU5UJ`yU&)ALy_4u%9DaeQIRrsjkOJC6Cdh zTnSXaHfi+@ZV&%n<6;Z%wDDVtG}#_^LxMYx?{m*gSecbQvG9$J*^r;>tA;Nzz3umJ z)^#Ny^>C4@8Xb?_@z-F-hIMtw?EHS~_?Dg>_VnRnSIxa@bhsU$sc{RkQZ$dH4*hTx zcXiybDl4nFZ0lDP#1SHp7i*qm$;=e7xVf{%?zH2v*re?V4SRMEz3e%PK{3qGfHEz< zqy2%R-Ep)mFV?_)E>4shN(Tu^u#xSwi)REiEmT#|#XnuotmLSOHy`Q93>!$2f3UNw-@osCwyj^W;ow;my5WXKiY4w2 z`YOM+ZBMfJeeQHw;k~OPLzyDfi4N1yN|G=AM-kLY*d8ynvaS7W;1}91k|6)+!sQH< zkw(d%WA6`z#)>zKeQv5ek9Dp8`ocS*p}%@)1`pf=2s?@YNrGjq<4FI~M;kVTUrP$S z95Yv?ww;| zV`rQW{T|Gs_nt>+%MPQ{ZV`^38vQb(vU}&QABS?c{VviL;wf;Cr;Bm_3D98QANkyW z>gj}sRv+VI-{mb3;+oJG$Q2&`V8|c&apT@y5*OSH~iSdq*{G}t!|BQz0*!J{s84r@N818u?WXIYc zG$RD1_sSgM*E64c ze9Z?p+*jm4M0@-`&N@7uU27liJLC%XFl>QHa&_zV`*(k|`i(rzNzSp$+W|V0*e)gu zOuB<)D9ufWxS$p$E-JcZ8uoQ*_#ZnyJ-Ok)@7^x&v6LXY;1dFz5{@Qqd^c;fu~9L2 z#ng4d;z{fkhK)XDQLbk!%OhjYS1y@CTp$TlMCD?gy8UJ0L!G0|9o>buHq};`_I_?n zzZ2Y0n+_A+wekM$kWWS|I`IW4KqNW8bI-28;Y_yT6H&ykIo07TyTcz2O~2vV9tsl< zilizoYfnLBadMY|xGB}WKDc|&3OUOod8N;v8f?Zgzk0Y$V78_#kDGpvjFdPL_`j2AYTN8z{UsQl zop$H+y_HmSP-O zS=h@eEm&Bg!=?9sBy|;!1_ontqnuYYHv^V*WgHL4F*yy4Iu{iPCCEHTcf^Fn!v4Ur zcd?^S9AShyXK_JVZcT>Csa)A!pKSr$E|+sYYwF{pU%OeN`3LFiZ1AudZj#SEF@>p$ zQ>mIur?Q`=n5?P^xwFJ1b^pq#HJkcQ1~?_#So&u280*(W%+nE!s%lds+#kq%bhpyI z!$thE*3Cp?S4Q$p*Npm`N88g(&UIvGGUGo%T(x0YrL=`gW){xypXLSebn#;<}~+lT798LaC;;tbi1r_(1X83W@ zx>22V9V&tVEBtD*ZEex_>bBt>Ywrw9K2o^xP0C?MiQwARFUXkkY1}Iht!(GG_!zs{ z5n68_{m3#2^vGV>Stw2sN-@2YE}CiBa-LUheC&%iu9t2e|6b$WvM%?d+ zVcN2FA^5?oYTT!f%GxR(8o#}5p0leVHM=j=F-SH)Ydwz<{pU>;y^4jb>)zsH-9>RL z&*eGpn2~2+oAqt4_)yp7Akg^Zp^9D=kG0TG?3}rz`t8Tg8t-o-#wNu@CC0aSx$0ae z#udKc!pEq%yAQ2yhV_3*ih1_Ermf;>;+emflPfAxPU`O0omMle%gh7hPo_zq}No0BMZ>r`V1VhVuz0!h(9&dcGcy$ z56>(7aj<0OPE&nrNlDY|vB>RzBbe^X!u#K{*SYk$4;uJB{lkXGP=4r(l;lj0!ro1o zr^YqZ*v~+^6BY}1F81OHJ+aT@keT!CB(JxYuaXFQ-b_Q5HQ2KLJbHo4V}v~GMoJzh zMq}^BPf+JpZPccg}(LkRb2% zd}Mva3D%#c7d8XVKQXkDX5T1m!&nO`)^=z$9EYn`q=we*buDzfpOahD0;|*@yL!O) zd_%Cl*_R9B;dy4|=qF$R>8%WU?~afO~9Ixu*L-Jd=mC7z_wAaa3hSAa!9N&09Zy^!8J019VLey z1hUO6k}MNYSCLS}M|O;I<_dfRFV!LJiMwn>P7=t6kLUt(DZwRw8HnMO2;UOK%XkRNB;)MMfu?I z8q-+W+yj1f=_SYFv1M??PHQA-FC&~CrNp!F(+>?&yd4iB<=1Wase|WwsugZx41XiN znF;w)jVHZ@2yn^F=p}>ZYf{q|>M0FA5jV*i2>cT=Sj0J8u$=1G5+HhHu!L~uhI}A{ zr3dwK8Wk*Uh;V|P1aoq)i>-^V3Ew-cV&1#6?uI}ew6~~pOM6>;n_g}Zp~(O9UqSb% YlD^TBir;5`%piucv2+mS3Ox`059dBzYXATM diff --git a/third_party/test/golden_widget/flutter_logo.memory.png b/third_party/test/golden_widget/flutter_logo.memory.png index fed8f95cd3721d71a16adff26df8729059c9924d..8d8d2c65e9c990f9717bad016fa762604a2965d3 100644 GIT binary patch literal 11111 zcmcI~`y*8A_y3+TF}+h}=tPCNAe>YxrzFN0494NeBu1rNaw`=n zBt?j*$*A1ANQ6Wox6b4??%%cdoX-3G{R2LJvF6!pz1DixTF-jc^X$$0-Ns_!f0q3R zL6C)8EZN%;M2dz`=Cs|u|65)?Sbd5w1Dzb%bvh#HEU|Y~#&!bKs zM4t-Aiv5R@r`EL=%dT7e`^Q^V+rw`2{*zc8mGEBAdh+Zwp7Zo2%f_nRIo5l39Q)|7 zuX4#s`p$RjvLaVl=R}y#)4o;Q5Zi7=_&!mpB!La|+zZ<(-R1xICx0UUp%vT$8jYkTzy1shy=Z#%9 z-rw9F{MI{oIC`@upOCbIi74raOl&&Cf)%KU>_stEQ)DtXpM*$TaAGfsos|egB#h3e z-onvU#uK=eB+3_chSCxozJeMlcS4>b%SUkO;{usYJh_N1T%_SxXIQd8=9vZ)>0O1v z9t7AC3>F9S?POG*$^y>y80R)n6<~_0;_iXx`!W0uT^yd-!$a|Xl!45Ykn%vfNys(8 zYa@?hbp(TjDQc*N6-S9A#J~&#dn->xd?V1=;M{0n3;{JpsxJGFKm_qI2GuV$pUWht zEF~e^6)0bJGK%-+1-%lspYCriw7@&5F%iqH7)}(4iri4g(9OWqH<K2^j^XmxR0om>v)PuRaUfj0T#+Jh|QlfToJ6n*?U{x_#=V}6xX^X+?`r--cXE9hN7a57cPNg^DH?;-<+& zE@CEfhhdb5nOHFayf-8WhX8>k!99*AP?uub+#?X2B^#YCk_0oqD1ki!QUpvY{S26J z7?aYa0BI&6je*pVkOzRACn3RH=Sob>c`Y~}FEOE$NaD_uc;q>Fbb-X&C@{AhODv=X zvZ>n=v!MlS=$4q%0{PgD1p;XS-eoJWS#AO_X$+UC3W_DE8w)GKor}5u3jnN^V4VPE ziV|gKU_K|Y`oV1l!!}`lWCr629p@#pTn?j4C8PeJVTXj*>o$~CredVr_FqNwML0CS zAIXVKtTY&+fu6L94d{@D12Rr!SRR$9JQ=;Em{Vx9m|FmfHAxhxBitBRNkR#!3d;uq zxLuyYv;`GQJHz4xG7W0rG8QNHq8JG<=OU1T+9KRYEP|7^l?+;Ok+2mEONg)03MRKw z9z#u4pjJ?MC{zVPBsu#CWVCs5&QtAAcC6zkk(v8_z!8zMJyzimr3P3?ae^4>cu>P-f~(fGS_)?j``9AG>q5Y?gBS%O()JmI1| z#T91wNDGIb&y!mRGt@KTGS`7hfed0zrp88!scIq|^AbowhXGOzdcX=c0BcPc5_&}< zRTG7TF8PPN1f%~jT!m2ysq-fiI!^&p=CBxtUjSVYfZemi6P7?hz92@NUlWKrP-RhV zP%mpB)lhODkQXH6RUn~3Ku13U87d*A@dUJZ16b@|NGKF<)G}8(6D{88B$|mNw0NUZ z=6C{Hyg?ZimLXcaQK>{E6pALr@eYH~CVQ*cyg0D2q%sycLTZmgfdNhHycPr;p9@HTs}4>>7#c19jKD zGhm zmxSv8k3a^}Tz@l;mB%BstY9poGb}AR6%#~KfNglgl7A&^xw=GpxS0ZFA(^5M#{y_> z!e}gq#XlKV+i-QY=;3F6GNdoXhgXtmHBn-BSTHmZu9i%dy-2)vv@-+JFkB#`x0S2w zKo7qa$&ZMXlb5G7fH%^4q}5g&JxKppF?WIl!61Hq{L{t+3Jy2Ln2v3o1GBAod7 z!N1R+WDnw)OP);BZXCMn;r&GWI_Lgier)_t1ELN}6BbSU|IO}Sjz6Ux;2LW)d{L~ITR0o4y?Zf+NK5W*RR91w=PxJjiUW2?&`R9Be*m9xc ziJkrFAgT;3B6Zf})}I1~uzbRZ-zYydoFG$uZ0I+Pe_B{=!L67V89VeZfF`V1byms0 z08q#DnBl(spA#;gPjZhWep~bt@P`7mfl9uZ_Valgm6?8!uD<5y^Ab~Tg>qyp=cmG6 zIEJ32vwo2NiFtY;T6u^^{|lhbbgpAt2L3Cs8p;@zwZ!)4l)MzE_o#H&VGAi@j0`@^j)m}v$eieyUo1HP+ zp%$MT%ojg;WIr>|^69qKnY)9>p`vqV$(x6l7RNO0#zU7|$=!1}& z&~nR@Xl}rFQlD{)P4pyF8oaMKo8Ygwq(qC|>$Zr77Mb`uN*h7|NIwNU)o;X3CmV8-^z+PKTqO&=AZtbGA z8Z7-)A{-kw-DHMEB+Tx5r;AlM9O|VK2k^bJhk^NstblS z8QixdYJ(ajuq($cZDxA?rz^j)z{Mpbn7^x%K*nb;#7!>f`Q};QiK@}F?MqHQhK*$# zc-L2(ab!h<4I;V%Gq3&zsVpn!D^*q8?J%_k{ktw3GpmW6ur2bscr3+hD9R7Re7(phclv&|Rm#MU}>g^;O9C z^*f~;2spg5PaYBcPNul2p{p2yYZR_pOcX>_S#+F%E@TI(Q(ig(%3@5O7);Aee+LcHm zpMXmx_g7hiIAkP6oDjCX{L#D7%)aebqCI{`;K`+{8!D7}{7v$-9y)_tSbR_l+93yo zd}2kXRCPt|GUr7CA)Xhz1H7}u>m9OCfdZ9d9FB?GT5sT%sWbMfvtq!T9#@&(|%;kTvm5YXGU0nDy>th_hNfnIIepO$JfCYf`>T0 zy}Det;xUh}+Pfz_QZ7BpAY^!+1MD$sMm!Q6c6YgXKL#H&0~vuo$fL@l9&FspEsW&jtT5e|d^hglZs758 zTbH3vuj*}d;1=@a?qi}^qgPilr8~onwm@niK^k!MRiG%pK7m>V_d2@nonZH9OudL7yo>Unm^X5qYd7|68T^V6cRXDN zH2^1j0Z!Z|oQ8x5RGlfPgT_a1=udQ(G&ro~@#MO@lhI$$f-$|}mzO-v?&Ws&&heQE zgALaOMR5ME9ttTS^ioBYPvd?hZExx)=bx-kyW`@L**>uvR5%@lyGSUO53c7LJI0^T zh}q|)%j3(1yp86s4t7T1jGJyRkjXJv4X&(!%hO)CX8cb9=tN>ja4v^~%C1uj~_R-OF4P_hBZmGfc-XW47ORx@UZL;_Q=eRdeovI%rp&uGsg=e$G!tbfHj) zD=pnzA2g{r+m&{AwmFUSEGKWGoL|*6_e08)KcA`qNBgH|_a8{Tvu0ID8S$ER>E?Ya zZKpd+=UfNJQr1LAYUNKg%H>VJKg%Xoz^*wG0X$t|@r(N0w(^;q1x*%>L-xjxCq;7S zNYIDkN6rziExeS-hsVV;if(!F+s$~tnl}!u^zxh@%8Mc)z!FP5c)`!VaCfTsFaNoT zzClxw-7Y(;U+k>n)}6DvePE)x`}<5b5f@o?J7)j{?AW)j*9a`M$z+Y}?AfG!AJZndUbr2* zZ1%3_$I|TQ5{WoC)gxgVtVi)FgSD6IAAc97ItKQQDc0_%c zfnUeE)NII<9lPG;1+@>Q&DfLiBbQ>1ALl%tc`;ggwlgD6>r!I0s76?6F{tX` z_e*Blg#O()aSP;L!wztdA^GXu8S$f&?%ggS#k;mW8G?{yyvjW!PjfrZpGnI$BQ|V> z3r;rCW%I|YE7K;5DM2S@{=R=FQP@}2p5~U9;!|g#k~tXda#`y@pi57E$d+&<2rl4P zu&eJycXe5K<*DrP`%Pi#+r##avkboek$MZ2t}*@k8sWj4f_|@o;P=~z4a;F`h#)S# zHJB6KSU=tR(JRmB)YJkwPDTr#KVvFw>)?0lbiL5*7GsgN-PQTH08=iaOlL(L4m{>E z$`2Xxw9Pd-)#J=jZuSWl+m#lam5mAcYPh`4HYcvB?ZZSe5oZ9mF3P6ivd^&WF`oLK z=2#l2#W=DdnR4dcklr?%<4@0ADxhA94{ZC5jQ34OaBx2OR)mJYcCO}0X<4v)^RC1? zuefis{6L-3q-g$&uV+@$3B7Ow1}BFbX?}$p?HM!eMeTb+`d);I)*89$TE!`u32GvS zmkacYX#;CQ&YhXaP?6D%($MMbT9o&-+8!WZ^%lD+DMWw!bUWWfvw zrv5zg8#&DL0n=w=s)W9I7BvGCSt|k=*SAe}>WT6{kjONqB3#MtfEHy#3_oP*T~+>i z%3Da3S?!*+Z8Gv}o&G%K+Po`Dls{f{j+E|#-Ok2(wV*lsE^xLsB|6jViR)N^cB5;R z8vUiaG6fu1HJipy^=S|049pC|G~sr~$DDp+A53#MV>FdwXfT}b|MZOD!j4*4y7&FF z&s3pp3DX`fV^5N3ZTAYw@_$&&eUnKuFc`KQv(e{&%kaDN?Ywa9t6aK2G=!w|1z^V} zUTkY&(R=&3-pr7WaB)Jjk7_{=N15@N6M9y513MgPhKVg8(KdN{=i~+VWzLQ6SnmH_ zIg+1s>uSw-ytB$wR$F9Qb4-`q(we2v%n_=$aS_K@;tR-(pwS)1qf)jxpUP%Br9Npj zexX(-co?p^WHETBN9(pF;;hf^oKmg)3-%d6ay!}7E_vv4F4CK?eL>o@4(d3XA=?d+@4ep^cGF!|MH<_Xc5X%gug;@9k&*Zu=DCKQnac z>=mcWGl_huN-SI{^On|g&RbJTHxILhgBP6CkVrjaS05Vm$jO_oEPXQf?b)l`mmZvL z_0w5nZkxvzElp1SzIOBQYg2FmT-w%z68D@>$r-(DEarvGj#TZio&Br1KTt%TT2GOY zTbc|jvb4u#`c*;RgRG+aBoKmkE;T%2V%~8M=hNHe{8l=_v!X7H^!~?s(}S6>-jAyXMQve(89V7F#fh$aE9Uu z$q5%(70JBVBZJR{Z;SW>p}zhh@9wUO3_rIcjIkq3dQ9R(uRo{8Fu)-kf!khqr@>0f zFDovb1nkUuXaWB?l4h}K=&1dA(b{I${T9k6>nsj*xg6I>2I*V(DzGPX!syhDl^Hpexi4W4?Eefuq!oBH#*k-$@jf3&+z*2KFB?kxG4p^THiOhzKF8v z@8~k9!>O=>=N6^4xd->gR<1T4?5n<8`}}%W@2mK{(%>_LQglKBTmZm1_k{Py<;PY& z86Nw-fAa>$SgOZwZJhGCtTuha;kC0jW4=!$G#9<`@l_tSFWVlDHv0(L_7*)XFPYrz zJva0)I@8;Du41FrDc5eb?3w16vXEq3ir*>c?u@OKWIKyrO6?A9%>K}}`J<}|Y?l`B z66i4fOM1>|W8YV{_>10MHSTo0Mvw?14mwmmZe7lr@J$1s)QqyuLb-TBcEz# z!Hcu9M|K`6Qhn}Mw)o?5Z9kXAN2_#L+)a=JTV#z`g-!PMvrQpl8KF?vuH7?!`kj|x zzfXD~Sx(k1k$o23!!V5-}0{)wn*>T7< zxf;l@(Z1>$iz$um@$#FGYoo$hc>){9m&;YoLOn83DIUhj3LEIIfkCIfDtJ##^`9N* z4Ach*zVr`35Ad*Y;BD>^H%5zGOyqHyLBY)r=Ve?n_QwpKcD^sj4uh%=MKZSGce?Ab zpu?#A*l2WS+T-5>gZ%b1&eFo(E^L0A$nUFo3mZYAaA>IPP4cJ8<5mMzH$VLPDqpqf z(E40~m(D}om`x-aQwqw&_8@*NEaA(x(|;G`dAAy^fYo9+RMwM`>sB|dH1}g*<*M%J zZ39=pkgpC={rP)xt85(iij|hI!VyKt1o{4B;U2k0MX1`VWY6fN!-a<^)oy+M9Kn3rvGFrATW4T@Y*67E6aBtcn3$YOTu3`->ryQ@@ey7<~ z+O6E))-6z!$+4*FOG|#&)%7#b@SZzU3S@MbDV8XKCD;1+bZt99xv{-zCH{(tuQuDTz=cU z%U-9^b;ZqPnOlD=2w!Ox_lMt6d!AOthdm|a%^Cgq`&MOcdUQ{*Pu$zHkutqpbgjv_ zY3z4ya_e!NfzHYBWW8ZKt3FE@3p={J(X&41aoE86t>GBc<6tZch?HDRIOf2+jpnlXn3FT$gRQJ zdgD{uIOpR{cD-$mdHrU;&o(y`t6gR)hmV|TbYFMuL3K6uH!RLJ z0xv=Z?d8dmPb7)8WR5V+0|O1Lme$q;Z;N-f9*-K3dEu-5{xh=FLYVWRjI;iFN$bCbzbysTm+riQ z3ByaPhV`E8>f2pvR)Tivk+7@vZt;g|S63#@G)KzkKTsaMtjG@fdLi=Wov45)$2cNx z1>}X?s&%Y7=oF$m*B317y7wUs*F2TD#Rm>u4khwmD;3RWIuzNCC5-Pyg2$00c&W_v zUPWisDO28B_pX1PU-aGOdyBf^m0Y%=_^H+_zPX{#$^G7;W(qXj(~$YX?xnPzD1L(B z3jdJi#?vnvUFW~=J+Tw`9E0rQR@RSyXf2ngp{KO;o^CQtk;k9Ow70(E6usJPPq1Eg z{~F%uzb}X`uB6z`XtJE|wSLA)r@tT;yK~OV{o;78uP?*SDdec&M~0nw{E-9SuAAOi z$tKEPEH$iP>H%6bzprn>^^&o_)|QAaM!uG^YYKc~7<6-ZQFJaS)gKx`q)uEQZt~`w z&uu;TIy%0pw@T6cyy|%^jXrpD9z-WdKW|fYcCJ&PxdBw@)l0pnkME4nMWV7%#u}clAD+eUqj72=4q6Qu}EP{a?uVu#Q|g-QP2Lu~W}2iXSLv z99t9fdNf|(KCydSm?_7{i%tlrPoX$h4E;jWd~Wg3S0nq_nscv56)jGEosh9vuSn5j zg){Str=(3G+vYQ z$HY84C-CrBMfPudm!<9Ae@^VYmQ5VFXp2MWhm>ihEB!;h6@`oh&b{n@`7$G;XXdL` z<94>dwaS#!fG6Y2x-KEypf!Q7p1s;wWbAl7xEa3UN3i7DP{&D~3v$S5FdTzdngnEg{6p79O2FU6pR{gH z{xkj}lYnFnqvLz`&pERnJ91(ph@o|&Ex3wrMq}dIvsX4U9O8eRkf1!zoQJrf+aZH(<1n{qAhb zv)}*Z@mT2T0nt@Yxq14Db07c19S($FO;?H*trGs}*LZ41)U$g{*#^dsh*J1SNgqC_ z@L5X_4`&m{9{mDE&on$XmKe%`&(>>nv5r&`#htF7vIkjNJ7dp$*GMsr5 zCNU97f>#0!D69>}>If%K>Ke?1)#e~|6*H^{46C-qrjCA%F2Z>0fVW{4 zhL8;3L8VI!(@%jHE=WaU(3ge&Y5U4XTC%z_AOg3nv=0P(p6PGu$`^XW>-6dxSt8Ol z+Bfcm^`3T}mrwl4W06)C8yEoL_CT$b~n{}07^R~Y~R literal 9850 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 YlD^TBir;5`%piucv2+mS3Ox`059dBzYXATM diff --git a/third_party/test/golden_widget/flutter_logo.network.png b/third_party/test/golden_widget/flutter_logo.network.png index fed8f95cd3721d71a16adff26df8729059c9924d..8d8d2c65e9c990f9717bad016fa762604a2965d3 100644 GIT binary patch literal 11111 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 literal 9850 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 YlD^TBir;5`%piucv2+mS3Ox`059dBzYXATM diff --git a/third_party/test/golden_widget/flutter_logo.string.png b/third_party/test/golden_widget/flutter_logo.string.png index fed8f95cd3721d71a16adff26df8729059c9924d..8d8d2c65e9c990f9717bad016fa762604a2965d3 100644 GIT binary patch literal 11111 zcmcI~`y*8A_y3+TF}+h}=tPCNAe>YxrzFN0494NeBu1rNaw`=n zBt?j*$*A1ANQ6Wox6b4??%%cdoX-3G{R2LJvF6!pz1DixTF-jc^X$$0-Ns_!f0q3R zL6C)8EZN%;M2dz`=Cs|u|65)?Sbd5w1Dzb%bvh#HEU|Y~#&!bKs zM4t-Aiv5R@r`EL=%dT7e`^Q^V+rw`2{*zc8mGEBAdh+Zwp7Zo2%f_nRIo5l39Q)|7 zuX4#s`p$RjvLaVl=R}y#)4o;Q5Zi7=_&!mpB!La|+zZ<(-R1xICx0UUp%vT$8jYkTzy1shy=Z#%9 z-rw9F{MI{oIC`@upOCbIi74raOl&&Cf)%KU>_stEQ)DtXpM*$TaAGfsos|egB#h3e z-onvU#uK=eB+3_chSCxozJeMlcS4>b%SUkO;{usYJh_N1T%_SxXIQd8=9vZ)>0O1v z9t7AC3>F9S?POG*$^y>y80R)n6<~_0;_iXx`!W0uT^yd-!$a|Xl!45Ykn%vfNys(8 zYa@?hbp(TjDQc*N6-S9A#J~&#dn->xd?V1=;M{0n3;{JpsxJGFKm_qI2GuV$pUWht zEF~e^6)0bJGK%-+1-%lspYCriw7@&5F%iqH7)}(4iri4g(9OWqH<K2^j^XmxR0om>v)PuRaUfj0T#+Jh|QlfToJ6n*?U{x_#=V}6xX^X+?`r--cXE9hN7a57cPNg^DH?;-<+& zE@CEfhhdb5nOHFayf-8WhX8>k!99*AP?uub+#?X2B^#YCk_0oqD1ki!QUpvY{S26J z7?aYa0BI&6je*pVkOzRACn3RH=Sob>c`Y~}FEOE$NaD_uc;q>Fbb-X&C@{AhODv=X zvZ>n=v!MlS=$4q%0{PgD1p;XS-eoJWS#AO_X$+UC3W_DE8w)GKor}5u3jnN^V4VPE ziV|gKU_K|Y`oV1l!!}`lWCr629p@#pTn?j4C8PeJVTXj*>o$~CredVr_FqNwML0CS zAIXVKtTY&+fu6L94d{@D12Rr!SRR$9JQ=;Em{Vx9m|FmfHAxhxBitBRNkR#!3d;uq zxLuyYv;`GQJHz4xG7W0rG8QNHq8JG<=OU1T+9KRYEP|7^l?+;Ok+2mEONg)03MRKw z9z#u4pjJ?MC{zVPBsu#CWVCs5&QtAAcC6zkk(v8_z!8zMJyzimr3P3?ae^4>cu>P-f~(fGS_)?j``9AG>q5Y?gBS%O()JmI1| z#T91wNDGIb&y!mRGt@KTGS`7hfed0zrp88!scIq|^AbowhXGOzdcX=c0BcPc5_&}< zRTG7TF8PPN1f%~jT!m2ysq-fiI!^&p=CBxtUjSVYfZemi6P7?hz92@NUlWKrP-RhV zP%mpB)lhODkQXH6RUn~3Ku13U87d*A@dUJZ16b@|NGKF<)G}8(6D{88B$|mNw0NUZ z=6C{Hyg?ZimLXcaQK>{E6pALr@eYH~CVQ*cyg0D2q%sycLTZmgfdNhHycPr;p9@HTs}4>>7#c19jKD zGhm zmxSv8k3a^}Tz@l;mB%BstY9poGb}AR6%#~KfNglgl7A&^xw=GpxS0ZFA(^5M#{y_> z!e}gq#XlKV+i-QY=;3F6GNdoXhgXtmHBn-BSTHmZu9i%dy-2)vv@-+JFkB#`x0S2w zKo7qa$&ZMXlb5G7fH%^4q}5g&JxKppF?WIl!61Hq{L{t+3Jy2Ln2v3o1GBAod7 z!N1R+WDnw)OP);BZXCMn;r&GWI_Lgier)_t1ELN}6BbSU|IO}Sjz6Ux;2LW)d{L~ITR0o4y?Zf+NK5W*RR91w=PxJjiUW2?&`R9Be*m9xc ziJkrFAgT;3B6Zf})}I1~uzbRZ-zYydoFG$uZ0I+Pe_B{=!L67V89VeZfF`V1byms0 z08q#DnBl(spA#;gPjZhWep~bt@P`7mfl9uZ_Valgm6?8!uD<5y^Ab~Tg>qyp=cmG6 zIEJ32vwo2NiFtY;T6u^^{|lhbbgpAt2L3Cs8p;@zwZ!)4l)MzE_o#H&VGAi@j0`@^j)m}v$eieyUo1HP+ zp%$MT%ojg;WIr>|^69qKnY)9>p`vqV$(x6l7RNO0#zU7|$=!1}& z&~nR@Xl}rFQlD{)P4pyF8oaMKo8Ygwq(qC|>$Zr77Mb`uN*h7|NIwNU)o;X3CmV8-^z+PKTqO&=AZtbGA z8Z7-)A{-kw-DHMEB+Tx5r;AlM9O|VK2k^bJhk^NstblS z8QixdYJ(ajuq($cZDxA?rz^j)z{Mpbn7^x%K*nb;#7!>f`Q};QiK@}F?MqHQhK*$# zc-L2(ab!h<4I;V%Gq3&zsVpn!D^*q8?J%_k{ktw3GpmW6ur2bscr3+hD9R7Re7(phclv&|Rm#MU}>g^;O9C z^*f~;2spg5PaYBcPNul2p{p2yYZR_pOcX>_S#+F%E@TI(Q(ig(%3@5O7);Aee+LcHm zpMXmx_g7hiIAkP6oDjCX{L#D7%)aebqCI{`;K`+{8!D7}{7v$-9y)_tSbR_l+93yo zd}2kXRCPt|GUr7CA)Xhz1H7}u>m9OCfdZ9d9FB?GT5sT%sWbMfvtq!T9#@&(|%;kTvm5YXGU0nDy>th_hNfnIIepO$JfCYf`>T0 zy}Det;xUh}+Pfz_QZ7BpAY^!+1MD$sMm!Q6c6YgXKL#H&0~vuo$fL@l9&FspEsW&jtT5e|d^hglZs758 zTbH3vuj*}d;1=@a?qi}^qgPilr8~onwm@niK^k!MRiG%pK7m>V_d2@nonZH9OudL7yo>Unm^X5qYd7|68T^V6cRXDN zH2^1j0Z!Z|oQ8x5RGlfPgT_a1=udQ(G&ro~@#MO@lhI$$f-$|}mzO-v?&Ws&&heQE zgALaOMR5ME9ttTS^ioBYPvd?hZExx)=bx-kyW`@L**>uvR5%@lyGSUO53c7LJI0^T zh}q|)%j3(1yp86s4t7T1jGJyRkjXJv4X&(!%hO)CX8cb9=tN>ja4v^~%C1uj~_R-OF4P_hBZmGfc-XW47ORx@UZL;_Q=eRdeovI%rp&uGsg=e$G!tbfHj) zD=pnzA2g{r+m&{AwmFUSEGKWGoL|*6_e08)KcA`qNBgH|_a8{Tvu0ID8S$ER>E?Ya zZKpd+=UfNJQr1LAYUNKg%H>VJKg%Xoz^*wG0X$t|@r(N0w(^;q1x*%>L-xjxCq;7S zNYIDkN6rziExeS-hsVV;if(!F+s$~tnl}!u^zxh@%8Mc)z!FP5c)`!VaCfTsFaNoT zzClxw-7Y(;U+k>n)}6DvePE)x`}<5b5f@o?J7)j{?AW)j*9a`M$z+Y}?AfG!AJZndUbr2* zZ1%3_$I|TQ5{WoC)gxgVtVi)FgSD6IAAc97ItKQQDc0_%c zfnUeE)NII<9lPG;1+@>Q&DfLiBbQ>1ALl%tc`;ggwlgD6>r!I0s76?6F{tX` z_e*Blg#O()aSP;L!wztdA^GXu8S$f&?%ggS#k;mW8G?{yyvjW!PjfrZpGnI$BQ|V> z3r;rCW%I|YE7K;5DM2S@{=R=FQP@}2p5~U9;!|g#k~tXda#`y@pi57E$d+&<2rl4P zu&eJycXe5K<*DrP`%Pi#+r##avkboek$MZ2t}*@k8sWj4f_|@o;P=~z4a;F`h#)S# zHJB6KSU=tR(JRmB)YJkwPDTr#KVvFw>)?0lbiL5*7GsgN-PQTH08=iaOlL(L4m{>E z$`2Xxw9Pd-)#J=jZuSWl+m#lam5mAcYPh`4HYcvB?ZZSe5oZ9mF3P6ivd^&WF`oLK z=2#l2#W=DdnR4dcklr?%<4@0ADxhA94{ZC5jQ34OaBx2OR)mJYcCO}0X<4v)^RC1? zuefis{6L-3q-g$&uV+@$3B7Ow1}BFbX?}$p?HM!eMeTb+`d);I)*89$TE!`u32GvS zmkacYX#;CQ&YhXaP?6D%($MMbT9o&-+8!WZ^%lD+DMWw!bUWWfvw zrv5zg8#&DL0n=w=s)W9I7BvGCSt|k=*SAe}>WT6{kjONqB3#MtfEHy#3_oP*T~+>i z%3Da3S?!*+Z8Gv}o&G%K+Po`Dls{f{j+E|#-Ok2(wV*lsE^xLsB|6jViR)N^cB5;R z8vUiaG6fu1HJipy^=S|049pC|G~sr~$DDp+A53#MV>FdwXfT}b|MZOD!j4*4y7&FF z&s3pp3DX`fV^5N3ZTAYw@_$&&eUnKuFc`KQv(e{&%kaDN?Ywa9t6aK2G=!w|1z^V} zUTkY&(R=&3-pr7WaB)Jjk7_{=N15@N6M9y513MgPhKVg8(KdN{=i~+VWzLQ6SnmH_ zIg+1s>uSw-ytB$wR$F9Qb4-`q(we2v%n_=$aS_K@;tR-(pwS)1qf)jxpUP%Br9Npj zexX(-co?p^WHETBN9(pF;;hf^oKmg)3-%d6ay!}7E_vv4F4CK?eL>o@4(d3XA=?d+@4ep^cGF!|MH<_Xc5X%gug;@9k&*Zu=DCKQnac z>=mcWGl_huN-SI{^On|g&RbJTHxILhgBP6CkVrjaS05Vm$jO_oEPXQf?b)l`mmZvL z_0w5nZkxvzElp1SzIOBQYg2FmT-w%z68D@>$r-(DEarvGj#TZio&Br1KTt%TT2GOY zTbc|jvb4u#`c*;RgRG+aBoKmkE;T%2V%~8M=hNHe{8l=_v!X7H^!~?s(}S6>-jAyXMQve(89V7F#fh$aE9Uu z$q5%(70JBVBZJR{Z;SW>p}zhh@9wUO3_rIcjIkq3dQ9R(uRo{8Fu)-kf!khqr@>0f zFDovb1nkUuXaWB?l4h}K=&1dA(b{I${T9k6>nsj*xg6I>2I*V(DzGPX!syhDl^Hpexi4W4?Eefuq!oBH#*k-$@jf3&+z*2KFB?kxG4p^THiOhzKF8v z@8~k9!>O=>=N6^4xd->gR<1T4?5n<8`}}%W@2mK{(%>_LQglKBTmZm1_k{Py<;PY& z86Nw-fAa>$SgOZwZJhGCtTuha;kC0jW4=!$G#9<`@l_tSFWVlDHv0(L_7*)XFPYrz zJva0)I@8;Du41FrDc5eb?3w16vXEq3ir*>c?u@OKWIKyrO6?A9%>K}}`J<}|Y?l`B z66i4fOM1>|W8YV{_>10MHSTo0Mvw?14mwmmZe7lr@J$1s)QqyuLb-TBcEz# z!Hcu9M|K`6Qhn}Mw)o?5Z9kXAN2_#L+)a=JTV#z`g-!PMvrQpl8KF?vuH7?!`kj|x zzfXD~Sx(k1k$o23!!V5-}0{)wn*>T7< zxf;l@(Z1>$iz$um@$#FGYoo$hc>){9m&;YoLOn83DIUhj3LEIIfkCIfDtJ##^`9N* z4Ach*zVr`35Ad*Y;BD>^H%5zGOyqHyLBY)r=Ve?n_QwpKcD^sj4uh%=MKZSGce?Ab zpu?#A*l2WS+T-5>gZ%b1&eFo(E^L0A$nUFo3mZYAaA>IPP4cJ8<5mMzH$VLPDqpqf z(E40~m(D}om`x-aQwqw&_8@*NEaA(x(|;G`dAAy^fYo9+RMwM`>sB|dH1}g*<*M%J zZ39=pkgpC={rP)xt85(iij|hI!VyKt1o{4B;U2k0MX1`VWY6fN!-a<^)oy+M9Kn3rvGFrATW4T@Y*67E6aBtcn3$YOTu3`->ryQ@@ey7<~ z+O6E))-6z!$+4*FOG|#&)%7#b@SZzU3S@MbDV8XKCD;1+bZt99xv{-zCH{(tuQuDTz=cU z%U-9^b;ZqPnOlD=2w!Ox_lMt6d!AOthdm|a%^Cgq`&MOcdUQ{*Pu$zHkutqpbgjv_ zY3z4ya_e!NfzHYBWW8ZKt3FE@3p={J(X&41aoE86t>GBc<6tZch?HDRIOf2+jpnlXn3FT$gRQJ zdgD{uIOpR{cD-$mdHrU;&o(y`t6gR)hmV|TbYFMuL3K6uH!RLJ z0xv=Z?d8dmPb7)8WR5V+0|O1Lme$q;Z;N-f9*-K3dEu-5{xh=FLYVWRjI;iFN$bCbzbysTm+riQ z3ByaPhV`E8>f2pvR)Tivk+7@vZt;g|S63#@G)KzkKTsaMtjG@fdLi=Wov45)$2cNx z1>}X?s&%Y7=oF$m*B317y7wUs*F2TD#Rm>u4khwmD;3RWIuzNCC5-Pyg2$00c&W_v zUPWisDO28B_pX1PU-aGOdyBf^m0Y%=_^H+_zPX{#$^G7;W(qXj(~$YX?xnPzD1L(B z3jdJi#?vnvUFW~=J+Tw`9E0rQR@RSyXf2ngp{KO;o^CQtk;k9Ow70(E6usJPPq1Eg z{~F%uzb}X`uB6z`XtJE|wSLA)r@tT;yK~OV{o;78uP?*SDdec&M~0nw{E-9SuAAOi z$tKEPEH$iP>H%6bzprn>^^&o_)|QAaM!uG^YYKc~7<6-ZQFJaS)gKx`q)uEQZt~`w z&uu;TIy%0pw@T6cyy|%^jXrpD9z-WdKW|fYcCJ&PxdBw@)l0pnkME4nMWV7%#u}clAD+eUqj72=4q6Qu}EP{a?uVu#Q|g-QP2Lu~W}2iXSLv z99t9fdNf|(KCydSm?_7{i%tlrPoX$h4E;jWd~Wg3S0nq_nscv56)jGEosh9vuSn5j zg){Str=(3G+vYQ z$HY84C-CrBMfPudm!<9Ae@^VYmQ5VFXp2MWhm>ihEB!;h6@`oh&b{n@`7$G;XXdL` z<94>dwaS#!fG6Y2x-KEypf!Q7p1s;wWbAl7xEa3UN3i7DP{&D~3v$S5FdTzdngnEg{6p79O2FU6pR{gH z{xkj}lYnFnqvLz`&pERnJ91(ph@o|&Ex3wrMq}dIvsX4U9O8eRkf1!zoQJrf+aZH(<1n{qAhb zv)}*Z@mT2T0nt@Yxq14Db07c19S($FO;?H*trGs}*LZ41)U$g{*#^dsh*J1SNgqC_ z@L5X_4`&m{9{mDE&on$XmKe%`&(>>nv5r&`#htF7vIkjNJ7dp$*GMsr5 zCNU97f>#0!D69>}>If%K>Ke?1)#e~|6*H^{46C-qrjCA%F2Z>0fVW{4 zhL8;3L8VI!(@%jHE=WaU(3ge&Y5U4XTC%z_AOg3nv=0P(p6PGu$`^XW>-6dxSt8Ol z+Bfcm^`3T}mrwl4W06)C8yEoL_CT$b~n{}07^R~Y~R literal 9850 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 YlD^TBir;5`%piucv2+mS3Ox`059dBzYXATM diff --git a/third_party/test/golden_widget/flutter_logo.string.rtl.png b/third_party/test/golden_widget/flutter_logo.string.rtl.png index 691515f3af73ba8d5a0de55486ba96d4a045c376..faede873117038b4871e008ad0b37153085713e8 100644 GIT binary patch literal 11653 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 B)_4E_ diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index be875230a872..6d3ac43ae9b7 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -68,6 +68,7 @@ Future main() async { goldenDir.createSync(recursive: true); } final File output = new File(pathName); + await output.writeAsBytes(await getSvgPngBytes(await fe.readAsString())); } } From 1c165f85d88afa43a9ac7429de265284351f1e96 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Sep 2018 20:12:54 -0700 Subject: [PATCH 147/512] format/analyzer fix --- third_party/example/lib/main.dart | 2 +- third_party/lib/src/svg/xml_parsers.dart | 73 +++++++++++++----------- third_party/lib/src/svg_parser.dart | 6 +- third_party/lib/src/vector_drawable.dart | 7 ++- 4 files changed, 50 insertions(+), 38 deletions(-) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index c8fec93b7b54..7544e1947e0f 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -166,4 +166,4 @@ class _MyHomePageState extends State { ]), ); } -} \ No newline at end of file +} diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index fcf8298fdb4d..8375e507035d 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -58,12 +58,13 @@ String buildUrlIri(XmlElement def) => 'url(#${getAttribute(def, 'id')})'; /// Parses a element, extracting and elements into the `paintServers` map. /// /// Returns any elements it was not able to process. -Iterable parseDefs( - XmlElement el, DrawableDefinitionServer definitions, Rect rootBounds) sync* { +Iterable parseDefs(XmlElement el, + DrawableDefinitionServer definitions, Rect rootBounds) sync* { for (XmlNode def in el.children) { if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { - definitions.addPaintServer(buildUrlIri(def), parseGradient(def, rootBounds)); + definitions.addPaintServer( + buildUrlIri(def), parseGradient(def, rootBounds)); } else if (def.name.local == 'clipPath') { definitions.addClipPath(buildUrlIri(def), parseClipPathDefinition(def)); } else { @@ -115,7 +116,8 @@ void parseStops( /// Parses an SVG element into a [Paint]. PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { - final String gradientUnits = getAttribute(el, 'gradientUnits', def: 'objectBoundingBox'); + final String gradientUnits = + getAttribute(el, 'gradientUnits', def: 'objectBoundingBox'); final bool isObjectBoundingBox = gradientUnits == 'objectBoundingBox'; final String x1 = getAttribute(el, 'x1', def: '0%'); @@ -130,15 +132,18 @@ PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { parseStops(stops, colors, offsets); - final Matrix4 originalTransform = parseTransform(getAttribute(el, 'gradientTransform', def: null)); - + final Matrix4 originalTransform = + parseTransform(getAttribute(el, 'gradientTransform', def: null)); + return (Rect bounds) { Vector3 from, to; Matrix4 transform = originalTransform?.clone() ?? new Matrix4.identity(); if (isObjectBoundingBox) { - final Matrix4 scale = affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); - final Matrix4 translate = affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); + final Matrix4 scale = + affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); + final Matrix4 translate = + affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); transform = translate.multiplied(scale)..multiply(transform); final Offset fromOffset = new Offset( @@ -163,21 +168,20 @@ PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { } else { final Offset fromOffset = new Offset( _isPercentage(x1) - ? _parsePercentage(x1) * rootBounds.width + rootBounds.left - : double.parse(x1), + ? _parsePercentage(x1) * rootBounds.width + rootBounds.left + : double.parse(x1), _isPercentage(y1) - ? _parsePercentage(y1) * rootBounds.height + rootBounds.top - : double.parse(y1), + ? _parsePercentage(y1) * rootBounds.height + rootBounds.top + : double.parse(y1), ); - final Offset toOffset = new Offset( _isPercentage(x2) - ? _parsePercentage(x2) * rootBounds.width + rootBounds.left - : double.parse(x2), + ? _parsePercentage(x2) * rootBounds.width + rootBounds.left + : double.parse(x2), _isPercentage(y2) - ? _parsePercentage(y2) * rootBounds.height + rootBounds.top - : double.parse(y2), + ? _parsePercentage(y2) * rootBounds.height + rootBounds.top + : double.parse(y2), ); from = new Vector3(fromOffset.dx, fromOffset.dy, 0.0); @@ -201,7 +205,8 @@ PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { /// Parses a into a [Paint]. PaintServer parseRadialGradient(XmlElement el, Rect rootBounds) { - final String gradientUnits = getAttribute(el, 'gradientUnits', def: 'objectBoundingBox'); + final String gradientUnits = + getAttribute(el, 'gradientUnits', def: 'objectBoundingBox'); final bool isObjectBoundingBox = gradientUnits == 'objectBoundingBox'; final String rawCx = getAttribute(el, 'cx', def: '50%'); @@ -217,15 +222,18 @@ PaintServer parseRadialGradient(XmlElement el, Rect rootBounds) { final List offsets = new List(stops.length); parseStops(stops, colors, offsets); - final Matrix4 originalTransform = parseTransform(getAttribute(el, 'gradientTransform', def: null)); + final Matrix4 originalTransform = + parseTransform(getAttribute(el, 'gradientTransform', def: null)); return (Rect bounds) { double cx, cy, r, fx, fy; Matrix4 transform = originalTransform?.clone() ?? new Matrix4.identity(); if (isObjectBoundingBox) { - final Matrix4 scale = affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); - final Matrix4 translate = affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); + final Matrix4 scale = + affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); + final Matrix4 translate = + affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); transform = translate.multiplied(scale)..multiply(transform); cx = _parseDecimalOrPercentage(rawCx); @@ -235,20 +243,21 @@ PaintServer parseRadialGradient(XmlElement el, Rect rootBounds) { fy = _parseDecimalOrPercentage(rawFy); } else { cx = _isPercentage(rawCx) - ? _parsePercentage(rawCx) * rootBounds.width + rootBounds.left - : double.parse(rawCx); + ? _parsePercentage(rawCx) * rootBounds.width + rootBounds.left + : double.parse(rawCx); cy = _isPercentage(rawCy) - ? _parsePercentage(rawCy) * rootBounds.height + rootBounds.top - : double.parse(rawCy); + ? _parsePercentage(rawCy) * rootBounds.height + rootBounds.top + : double.parse(rawCy); r = _isPercentage(rawR) - ? _parsePercentage(rawR) * ((rootBounds.height + rootBounds.width) / 2) - : double.parse(rawR); + ? _parsePercentage(rawR) * + ((rootBounds.height + rootBounds.width) / 2) + : double.parse(rawR); fx = _isPercentage(rawFx) - ? _parsePercentage(rawFx) * rootBounds.width + rootBounds.left - : double.parse(rawFx); + ? _parsePercentage(rawFx) * rootBounds.width + rootBounds.left + : double.parse(rawFx); fy = _isPercentage(rawFy) - ? _parsePercentage(rawFy) * rootBounds.height + rootBounds.top - : double.parse(rawFy); + ? _parsePercentage(rawFy) * rootBounds.height + rootBounds.top + : double.parse(rawFy); } final Offset center = new Offset(cx, cy); @@ -359,7 +368,7 @@ double parseOpacity(XmlElement el) { DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri, DrawableDefinitionServer definitions, Rect bounds, {double opacity}) { - Shader shader = definitions.getPaint(iri, bounds); + final Shader shader = definitions.getPaint(iri, bounds); if (shader == null) { FlutterError.onError( new FlutterErrorDetails( diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index bdf105a3b6a9..c2860e4cd758 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -12,7 +12,8 @@ import 'vector_drawable.dart'; /// An SVG Shape element that will be drawn to the canvas. class DrawableSvgShape extends DrawableShape { - const DrawableSvgShape(Path path, DrawableStyle style, this.transform) : super(path, style); + const DrawableSvgShape(Path path, DrawableStyle style, this.transform) + : super(path, style); final Matrix4 transform; @@ -116,7 +117,8 @@ Paint _transparentPaint = new Paint()..color = const Color(0x0); void _appendParagraphs(ParagraphBuilder fill, ParagraphBuilder stroke, String text, DrawableStyle style) { fill - ..pushStyle(style.textStyle.toFlutterTextStyle(foregroundOverride: style.fill)) + ..pushStyle( + style.textStyle.toFlutterTextStyle(foregroundOverride: style.fill)) ..addText(text); stroke diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 387e0e1fbaaf..bc6495836133 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -152,7 +152,8 @@ class DrawablePaint { return a._withGroupOpacity(groupOpacity); } - if (identical(a, DrawablePaint.empty) || identical(b, DrawablePaint.empty)) { + if (identical(a, DrawablePaint.empty) || + identical(b, DrawablePaint.empty)) { return (a ?? b)._withGroupOpacity(groupOpacity); } @@ -161,8 +162,8 @@ class DrawablePaint { } // If we got here, the styles should not be null. - assert( - a.style == b.style, 'Cannot merge Paints with different PaintStyles; got:\na: $a\nb: $b.'); + assert(a.style == b.style, + 'Cannot merge Paints with different PaintStyles; got:\na: $a\nb: $b.'); final Color mergedColor = a.color ?? b.color; From 5c9635795acb69dcfb4fde23ea7f221e23a64d9d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Sep 2018 20:18:33 -0700 Subject: [PATCH 148/512] make drawableTextStyle use DrawablePaint --- third_party/lib/src/vector_drawable.dart | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index bc6495836133..639cc4e3b08c 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -330,8 +330,8 @@ class DrawableTextStyle { final double wordSpacing; final double height; final Locale locale; - final Paint background; - final Paint foreground; + final DrawablePaint background; + final DrawablePaint foreground; TextStyle toFlutterTextStyle({DrawablePaint foregroundOverride}) { return new TextStyle( @@ -347,12 +347,9 @@ class DrawableTextStyle { wordSpacing: wordSpacing, height: height, locale: locale, - background: background, - color: foregroundOverride?.color ?? - foreground?.color ?? - const Color(0xFF000000), - // this will be supported in Flutter 0.5.6 or 0.5.7 - // foreground: foregroundOverride ?? foreground, + background: background?.toFlutterPaint(), + foreground: + foregroundOverride?.toFlutterPaint() ?? foreground?.toFlutterPaint(), ); } From f00a3430535ca8d962b9063ca73fa4c3f323e3a8 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Sep 2018 20:23:08 -0700 Subject: [PATCH 149/512] Fix another spot for DrawablePaint/Paint --- third_party/lib/src/svg_parser.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index c2860e4cd758..9eb224fd58d3 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -113,7 +113,8 @@ void _unhandledElement(XmlElement el, String key) { } } -Paint _transparentPaint = new Paint()..color = const Color(0x0); +const DrawablePaint _transparentStroke = + const DrawablePaint(PaintingStyle.stroke, color: const Color(0x0)); void _appendParagraphs(ParagraphBuilder fill, ParagraphBuilder stroke, String text, DrawableStyle style) { fill @@ -124,7 +125,7 @@ void _appendParagraphs(ParagraphBuilder fill, ParagraphBuilder stroke, stroke ..pushStyle(style.textStyle.toFlutterTextStyle( foregroundOverride: - style.stroke == null ? _transparentPaint : style.stroke)) + style.stroke == null ? _transparentStroke : style.stroke)) ..addText(text); } From f5e034b91d84bfdaa05b5c226a115f6f0572f24e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Sep 2018 20:50:24 -0700 Subject: [PATCH 150/512] fix viewport for non-zero min-x min-y --- third_party/example/lib/main.dart | 1 + third_party/lib/avd.dart | 8 ++-- third_party/lib/src/avd/xml_parsers.dart | 6 +-- third_party/lib/src/avd_parser.dart | 2 +- third_party/lib/src/svg/xml_parsers.dart | 23 ++++++---- third_party/lib/src/vector_drawable.dart | 57 ++++++++++++++++++++---- third_party/lib/svg.dart | 13 +++--- 7 files changed, 80 insertions(+), 30 deletions(-) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index 7544e1947e0f..f1d91fe9f469 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -17,6 +17,7 @@ const List assetNames = const [ 'assets/simple/text.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', + 'assets/simple/male.svg', 'assets/simple/radial_gradient.svg', 'assets/simple/rect_rrect.svg', 'assets/simple/rect_rrect_no_ry.svg', diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 08468cbfe509..3bf1a68e8b9b 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -29,7 +29,7 @@ class Avd { final Picture pic = avdRoot.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter); - return new PictureInfo(picture: pic, viewBox: avdRoot.viewBox); + return new PictureInfo(picture: pic, viewBox: avdRoot.viewport.rect); } FutureOr avdPictureStringDecoder(String raw, @@ -39,7 +39,7 @@ class Avd { picture: svg.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter), - viewBox: svg.viewBox); + viewBox: svg.viewport.rect); } FutureOr fromAvdBytes(Uint8List raw, String key) async { @@ -63,7 +63,7 @@ class Avd { /// Creates a [DrawableRoot] from a string of Android Vector Drawable data. DrawableRoot fromAvdString(String rawSvg, String key) { final XmlElement svg = xml.parse(rawSvg).rootElement; - final Rect viewBox = parseViewBox(svg); + final DrawableViewport viewBox = parseViewBox(svg); final List children = svg.children .where((XmlNode child) => child is XmlElement) .map((XmlNode child) => parseAvdElement( @@ -154,7 +154,7 @@ class AvdPicture extends SvgPicture { /// Creates a [DrawableRoot] from a string of SVG data. DrawableRoot fromAvdString(String rawSvg, Size size) { final XmlElement svg = xml.parse(rawSvg).rootElement; - final Rect viewBox = parseViewBox(svg); + final DrawableViewport viewBox = parseViewBox(svg); final List children = svg.children .where((XmlNode child) => child is XmlElement) .map((XmlNode child) => parseAvdElement( diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index 49d21902cd06..f397ef173f4e 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -11,17 +11,17 @@ import '../utilities/xml.dart'; const String androidNS = 'http://schemas.android.com/apk/res/android'; /// Parses an AVD @android:viewportWidth and @android:viewportHeight attributes to a [Rect]. -Rect parseViewBox(XmlElement el) { +DrawableViewport parseViewBox(XmlElement el) { final String rawWidth = getAttribute(el, 'viewportWidth', def: '', namespace: androidNS); final String rawHeight = getAttribute(el, 'viewportHeight', def: '', namespace: androidNS); if (rawWidth == '' || rawHeight == '') { - return Rect.zero; + return new DrawableViewport(Rect.zero); } final double width = double.parse(rawWidth); final double height = double.parse(rawHeight); - return new Rect.fromLTWH(0.0, 0.0, width, height); + return new DrawableViewport(Rect.fromLTWH(0.0, 0.0, width, height)); } Matrix4 parseTransform(XmlElement el) { diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index 29c69de914f7..7c4281bcfaa5 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -9,7 +9,7 @@ import 'utilities/xml.dart'; import 'vector_drawable.dart'; class DrawableAvdRoot extends DrawableRoot { - const DrawableAvdRoot(Rect viewBox, List children, + const DrawableAvdRoot(DrawableViewport viewBox, List children, DrawableDefinitionServer definitions, DrawableStyle style) : super(viewBox, children, definitions, style); } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 8375e507035d..4671e0c26934 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -24,7 +24,7 @@ const Map svgPathParsers = }; /// Parses an SVG @viewBox attribute (e.g. 0 0 100 100) to a [Rect]. -Rect parseViewBox(XmlElement svg) { +DrawableViewport parseViewBox(XmlElement svg) { final String viewBox = getAttribute(svg, 'viewBox'); if (viewBox == '') { @@ -34,22 +34,29 @@ Rect parseViewBox(XmlElement svg) { final String rawHeight = getAttribute(svg, 'height').replaceAll(notDigits, ''); if (rawWidth == '' || rawHeight == '') { - return Rect.zero; + return new DrawableViewport(Rect.zero); } final double width = double.parse(rawWidth); final double height = double.parse(rawHeight); - return new Rect.fromLTWH(0.0, 0.0, width, height); + return new DrawableViewport(Rect.fromLTWH(0.0, 0.0, width, height)); } final List parts = viewBox.split(new RegExp(r'[ ,]+')); if (parts.length < 4) { throw new StateError('viewBox element must be 4 elements long'); } - return new Rect.fromLTWH( - double.parse(parts[0]), - double.parse(parts[1]), - double.parse(parts[2]), - double.parse(parts[3]), + + return new DrawableViewport( + new Rect.fromLTWH( + 0.0, + 0.0, + double.parse(parts[2]), + double.parse(parts[3]), + ), + offset: new Offset( + -double.parse(parts[0]), + -double.parse(parts[1]), + ), ); } diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 639cc4e3b08c..43bdadabf7a7 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -441,10 +441,49 @@ class DrawableDefinitionServer { } } +/// Contains the viewport size and offset for a Drawable. +@immutable +class DrawableViewport { + /// Creates a new DrawableViewport, which acts as a bounding box for the Drawable + /// and specifies what offset (if any) the coordinate system needs to be translated by. + /// + /// Both `rect` and `offset` must not be null. + const DrawableViewport( + this.rect, { + this.offset = Offset.zero, + }) : assert(rect != null), + assert(offset != null); + + /// The offset for all drawing commands in this Drawable. + final Offset offset; + + /// The viewport size for the drawable. + final Rect rect; + + /// The top of the viewport rect. + double get top => rect.top; + /// The bottom of the viewport rect. + double get bottom => rect.bottom; + /// The left side of the viewport rect. + double get left => rect.left; + /// The right side of the viewport rect. + double get right => rect.right; + /// The width of the viewport rect. + double get width => rect.width; + /// The height of the viewport rect. + double get height => rect.height; + + @override + String toString() => 'DrawableViewport{$rect, $offset}'; +} + /// The root element of a drawable. class DrawableRoot implements Drawable { + const DrawableRoot( + this.viewport, this.children, this.definitions, this.style); + /// The expected coordinates used by child paths for drawing. - final Rect viewBox; + final DrawableViewport viewport; /// The actual child or group to draw. final List children; @@ -458,8 +497,6 @@ class DrawableRoot implements Drawable { /// The [DrawableStyle] for inheritence. final DrawableStyle style; - const DrawableRoot(this.viewBox, this.children, this.definitions, this.style); - /// Scales the `canvas` so that the drawing units in this [Drawable] /// will scale to the `desiredSize`. /// @@ -467,23 +504,27 @@ class DrawableRoot implements Drawable { /// the smaller dimension and translate to center the image along the larger /// dimension. void scaleCanvasToViewBox(Canvas canvas, Size desiredSize) { - render_picture.scaleCanvasToViewBox(canvas, desiredSize, viewBox); + render_picture.scaleCanvasToViewBox(canvas, desiredSize, viewport.rect); } /// Clips the canvas to a rect corresponding to the `viewBox`. void clipCanvasToViewBox(Canvas canvas) { - canvas.clipRect(viewBox.translate(viewBox.left, viewBox.top)); + canvas.clipRect( + viewport.rect.translate(viewport.rect.left, viewport.rect.top)); } @override bool get hasDrawableContent => - children.isNotEmpty == true && viewBox != null && !viewBox.isEmpty; + children.isNotEmpty == true && viewport != null && !viewport.rect.isEmpty; @override void draw(Canvas canvas, ColorFilter colorFilter) { if (!hasDrawableContent) { return; } + if (viewport.offset != Offset.zero) { + canvas.translate(viewport.offset.dx, viewport.offset.dy); + } for (Drawable child in children) { child.draw(canvas, colorFilter); } @@ -499,12 +540,12 @@ class DrawableRoot implements Drawable { /// particularly when it is eventually rasterized. Picture toPicture( {Size size, bool clipToViewBox = true, ColorFilter colorFilter}) { - if (viewBox == null || viewBox.size.width == 0) { + if (viewport == null || viewport.rect.size.width == 0) { return null; } final PictureRecorder recorder = new PictureRecorder(); - final Canvas canvas = new Canvas(recorder, viewBox); + final Canvas canvas = new Canvas(recorder, viewport.rect); canvas.save(); if (size != null) { scaleCanvasToViewBox(canvas, size); diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index dd9e0a79bf40..cdec47b0d904 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -48,7 +48,7 @@ class Svg { final Picture pic = svgRoot.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter); - return new PictureInfo(picture: pic, viewBox: svgRoot.viewBox); + return new PictureInfo(picture: pic, viewBox: svgRoot.viewport.rect); } /// Produces a [PictureInfo] from a [String] of SVG data. @@ -68,7 +68,7 @@ class Svg { picture: svg.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter), - viewBox: svg.viewBox); + viewBox: svg.viewport.rect); } /// Produces a [Drawableroot] from a [Uint8List] of SVG byte data (assumes UTF8 encoding). @@ -97,10 +97,11 @@ class Svg { /// The `key` is used for debugging purposes. DrawableRoot fromSvgString(String rawSvg, String key) { final XmlElement svg = xml.parse(rawSvg).rootElement; - final Rect viewBox = parseViewBox(svg); + final DrawableViewport viewBox = parseViewBox(svg); //final Map paintServers = {}; final DrawableDefinitionServer definitions = new DrawableDefinitionServer(); - final DrawableStyle style = parseStyle(svg, definitions, viewBox, null); + final DrawableStyle style = + parseStyle(svg, definitions, viewBox.rect, null); final List children = svg.children .where((XmlNode child) => child is XmlElement) @@ -108,7 +109,7 @@ class Svg { (XmlNode child) => parseSvgElement( child, definitions, - viewBox, + viewBox.rect, style, key, ), @@ -118,7 +119,7 @@ class Svg { viewBox, children, definitions, - parseStyle(svg, definitions, viewBox, null), + parseStyle(svg, definitions, viewBox.rect, null), ); } } From 2e847f64a80bd55f9b495dad04fc5d563ae0930c Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 11 Sep 2018 09:05:06 -0700 Subject: [PATCH 151/512] update tests, try to fix travis --- third_party/.travis.yml | 4 ++-- third_party/test/xml_svg_test.dart | 15 ++++++++++----- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/third_party/.travis.yml b/third_party/.travis.yml index c5ca9e92aa9b..bc9f40bee859 100644 --- a/third_party/.travis.yml +++ b/third_party/.travis.yml @@ -10,7 +10,7 @@ addons: - libstdc++6 - fonts-droid before_script: - - git clone https://github.com/flutter/flutter.git -b beta --single-branch + - git clone https://github.com/flutter/flutter.git -b dev --single-branch - ./flutter/bin/flutter doctor - gem install coveralls-lcov script: @@ -20,4 +20,4 @@ after_success: - coveralls-lcov coverage/lcov.info cache: directories: - - $HOME/.pub-cache \ No newline at end of file + - $HOME/.pub-cache diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index c474d1d6f5f3..7e622af40339 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -48,12 +48,17 @@ void main() { .rootElement; final XmlElement svgWithWidthHeight = parse('').rootElement; - + final XmlElement svgWithViewBoxMinXMinY = + parse('').rootElement; final XmlElement svgWithNoSizeInfo = parse('').rootElement; - expect(parseViewBox(svgWithViewBox), rect); - expect(parseViewBox(svgWithViewBoxAndWidthHeight), rect); - expect(parseViewBox(svgWithWidthHeight), rect); - expect(parseViewBox(svgWithNoSizeInfo), Rect.zero); + + expect(parseViewBox(svgWithViewBox).rect, rect); + expect(parseViewBox(svgWithViewBox).offset, Offset.zero); + expect(parseViewBox(svgWithViewBoxAndWidthHeight).rect, rect); + expect(parseViewBox(svgWithWidthHeight).rect, rect); + expect(parseViewBox(svgWithNoSizeInfo).rect, Rect.zero); + expect(parseViewBox(svgWithViewBoxMinXMinY).rect, rect); + expect(parseViewBox(svgWithViewBoxMinXMinY).offset, const Offset(-42.0, -56.0)); }); test('TileMode tests', () { From 93938caa8b0f620a47d561c7eafc637d179f9924 Mon Sep 17 00:00:00 2001 From: Stefano Rodriguez Date: Mon, 17 Sep 2018 21:23:59 +0200 Subject: [PATCH 152/512] Improve SvgPicture size handling (#60) * Improve SvgPicture size handling * Fix formatting * Fix behaviour * Fix missing fields in initializer * Add docs --- third_party/lib/svg.dart | 110 ++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 26 deletions(-) diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index cdec47b0d904..bbbf41f1e936 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -127,19 +127,20 @@ class Svg { /// A widget that will parse SVG data into a [Picture] using a [PictureProvider]. /// /// The picture will be cached using the [PictureCache], incorporating any color -/// filterting used into the key (meaning the same SVG with two different `color` +/// filtering used into the key (meaning the same SVG with two different `color` /// arguments applied would be two cache entries). class SvgPicture extends StatefulWidget { /// The default placeholder for a SVG that may take time to parse or - /// retreieve, e.g. from a network location. + /// retrieve, e.g. from a network location. static WidgetBuilder defaultPlaceholderBuilder = (BuildContext ctx) => const LimitedBox(); /// Instantiates a widget that renders an SVG picture using the `pictureProvider`. /// - /// If `width` or `height` are specified, a [SizedBox] will be used to dictate - /// the width and height of the rendered output. Otherwise, the picture will - /// be sized to its parent. + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. /// /// If `matchTextDirection` is set to true, the picture will be flipped /// horizontally in [TextDirection.rtl] contexts. @@ -155,6 +156,8 @@ class SvgPicture extends StatefulWidget { {Key key, this.width, this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, this.placeholderBuilder}) @@ -167,9 +170,10 @@ class SvgPicture extends StatefulWidget { /// from a package and null otherwise. See the `Assets in packages` section for /// details. /// - /// If `width` or `height` are specified, a [SizedBox] will be used to dictate - /// the width and height of the rendered output. Otherwise, the picture will - /// be sized to its parent. + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. /// /// If `matchTextDirection` is set to true, the picture will be flipped /// horizontally in [TextDirection.rtl] contexts. @@ -241,6 +245,8 @@ class SvgPicture extends StatefulWidget { String package, this.width, this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, this.allowDrawingOutsideViewBox = false, this.placeholderBuilder, Color color, @@ -257,11 +263,12 @@ class SvgPicture extends StatefulWidget { /// Creates a widget that displays a [PictureStream] obtained from the network. /// - /// The `url` argument must not be null. + /// The [url] argument must not be null. /// - /// If `width` or `height` are specified, a [SizedBox] will be used to dictate - /// the width and height of the rendered output. Otherwise, the picture will - /// be sized to its parent. + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. /// /// If `matchTextDirection` is set to true, the picture will be flipped /// horizontally in [TextDirection.rtl] contexts. @@ -286,6 +293,8 @@ class SvgPicture extends StatefulWidget { Map headers, this.width, this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, this.placeholderBuilder, @@ -304,9 +313,10 @@ class SvgPicture extends StatefulWidget { /// /// The [file] argument must not be null. /// - /// If `width` or `height` are specified, a [SizedBox] will be used to dictate - /// the width and height of the rendered output. Otherwise, the picture will - /// be sized to its parent. + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. /// /// If `matchTextDirection` is set to true, the picture will be flipped /// horizontally in [TextDirection.rtl] contexts. @@ -328,6 +338,8 @@ class SvgPicture extends StatefulWidget { {Key key, this.width, this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, this.placeholderBuilder, @@ -345,9 +357,10 @@ class SvgPicture extends StatefulWidget { /// /// The [bytes] argument must not be null. /// - /// If `width` or `height` are specified, a [SizedBox] will be used to dictate - /// the width and height of the rendered output. Otherwise, the picture will - /// be sized to its parent. + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. /// /// If `matchTextDirection` is set to true, the picture will be flipped /// horizontally in [TextDirection.rtl] contexts. @@ -366,6 +379,8 @@ class SvgPicture extends StatefulWidget { {Key key, this.width, this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, this.placeholderBuilder, @@ -383,9 +398,10 @@ class SvgPicture extends StatefulWidget { /// /// The [bytes] argument must not be null. /// - /// If `width` or `height` are specified, a [SizedBox] will be used to dictate - /// the width and height of the rendered output. Otherwise, the picture will - /// be sized to its parent. + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. /// /// If `matchTextDirection` is set to true, the picture will be flipped /// horizontally in [TextDirection.rtl] contexts. @@ -404,6 +420,8 @@ class SvgPicture extends StatefulWidget { {Key key, this.width, this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, this.placeholderBuilder, @@ -450,6 +468,34 @@ class SvgPicture extends StatefulWidget { /// will take the height of its parent. final double height; + /// How to inscribe the picture into the space allocated during layout. + /// The default is [BoxFit.contain]. + final BoxFit fit; + + /// How to align the picture within its parent widget. + /// + /// The alignment aligns the given position in the picture to the given position + /// in the layout bounds. For example, an [Alignment] alignment of (-1.0, + /// -1.0) aligns the image to the top-left corner of its layout bounds, while a + /// [Alignment] alignment of (1.0, 1.0) aligns the bottom right of the + /// picture with the bottom right corner of its layout bounds. Similarly, an + /// alignment of (0.0, 1.0) aligns the bottom middle of the image with the + /// middle of the bottom edge of its layout bounds. + /// + /// If the [alignment] is [TextDirection]-dependent (i.e. if it is a + /// [AlignmentDirectional]), then a [TextDirection] must be available + /// when the picture is painted. + /// + /// Defaults to [Alignment.center]. + /// + /// See also: + /// + /// * [Alignment], a class with convenient constants typically used to + /// specify an [AlignmentGeometry]. + /// * [AlignmentDirectional], like [Alignment] for specifying alignments + /// relative to text direction. + final Alignment alignment; + /// The [PictureProvider] used to resolve the SVG. final PictureProvider pictureProvider; @@ -554,16 +600,28 @@ class _SvgPictureState extends State { @override Widget build(BuildContext context) { if (_picture != null) { - final RawPicture picture = new RawPicture( + Widget picture = new RawPicture( _picture, matchTextDirection: widget.matchTextDirection, allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, ); - return widget.width != null || widget.height != null - ? new SizedBox( - height: widget.height, width: widget.width, child: picture) - : picture; + picture = new SizedBox.fromSize(size: _picture.viewBox.size, child: picture); + picture = new FittedBox(fit: widget.fit, alignment: widget.alignment, child: picture); + + double width = widget.width; + double height = widget.height; + if (width == null && height == null) { + width = _picture.viewBox.width; + height = _picture.viewBox.height; + } else if (height != null) { + width = height / _picture.viewBox.height * _picture.viewBox.width; + } else if (width != null) { + height = width / _picture.viewBox.width * _picture.viewBox.height; + } + + return new SizedBox(width: width, height: height, child: picture); } + return widget.placeholderBuilder == null ? _getDefaultPlaceholder(context, widget.width, widget.height) : widget.placeholderBuilder(context); From ca4b4da7286d8a1d640bed618860f64419d5bd15 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 17 Sep 2018 21:33:14 -0700 Subject: [PATCH 153/512] add test, print errors once --- third_party/example/assets/simple/male.svg | 2 ++ third_party/example/lib/main.dart | 10 ---------- third_party/golden/simple/male.png | Bin 0 -> 5502 bytes third_party/lib/src/svg_parser.dart | 13 +++++++++---- 4 files changed, 11 insertions(+), 14 deletions(-) create mode 100644 third_party/example/assets/simple/male.svg create mode 100644 third_party/golden/simple/male.png diff --git a/third_party/example/assets/simple/male.svg b/third_party/example/assets/simple/male.svg new file mode 100644 index 000000000000..208973591db7 --- /dev/null +++ b/third_party/example/assets/simple/male.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index f1d91fe9f469..dfac29a6f8f1 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -86,16 +86,6 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; - _painters.add(new SvgPicture.string( - ''' - - - - - - -''')); - for (String assetName in assetNames) { _painters.add( new SvgPicture.asset(assetName), diff --git a/third_party/golden/simple/male.png b/third_party/golden/simple/male.png new file mode 100644 index 0000000000000000000000000000000000000000..6b5c887f53eaaf0290cf061c1b97e5c50d993aea GIT binary patch literal 5502 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 literal 0 HcmV?d00001 diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 9eb224fd58d3..503bed3f918e 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -89,6 +89,8 @@ Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, return new DrawableNoop(el.name.local); } +Set _unhandledElements = new Set(); + void _unhandledElement(XmlElement el, String key) { if (el.name.local == 'style') { FlutterError.reportError(new FlutterErrorDetails( @@ -107,10 +109,13 @@ void _unhandledElement(XmlElement el, String key) { library: 'SVG', context: 'in parseSvgElement', )); - } else if (el.name.local != 'desc') { - // no plans to handle these - print('unhandled element ${el.name.local}; Picture key: $key'); - } + } + assert(() { + if (_unhandledElements.add(el.name.local)) { + print('unhandled element ${el.name.local}; Picture key: $key'); + } + return true; + }()); } const DrawablePaint _transparentStroke = From e4fdd88b278412ecfaf7a5bd59437cc2a0a620e7 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 18 Sep 2018 10:23:31 -0700 Subject: [PATCH 154/512] version bump --- third_party/CHANGELOG.md | 9 +++++++++ third_party/example/pubspec.lock | 2 +- third_party/pubspec.yaml | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index b36cda6d2856..ab44c93bace8 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,14 @@ # CHANGES +## 0.6.0 + +- **BREAKING** Update Flutter version dependencies/package dependencies +- Print unhandled errors only once, and only in debug mode (000e17f) +- Add ability to specify a `BoxFit` and `Alignment` for SvgPictures (Thanks @sroddy!). +- Support `userSpaceOnUse` gradientUnits (@sroddy) +- Miscellaneous bug fixes +- Restructure project to match expectations of Flutter tooling + ## 0.5.5 - Create a new class to encapsulate `Paint` and assist with inheriting all painting properties. diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index 64dfff14e174..30517cf147f4 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.5.5+1" + version: "0.6.0" meta: dependency: transitive description: diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 2490ad1b7653..5ea4d2168557 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.5.5+1 +version: 0.6.0 dependencies: path_drawing: ^0.3.0 From 3ca677d1e3782569cf663a9819eefb7e9f5e6c2b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 26 Sep 2018 15:05:48 -0700 Subject: [PATCH 155/512] better error for invalid viewBox/width/height --- third_party/lib/src/svg/xml_parsers.dart | 11 +++++++++-- third_party/lib/src/svg_parser.dart | 2 +- third_party/lib/src/vector_drawable.dart | 7 ++++++- third_party/lib/svg.dart | 6 ++++-- third_party/test/xml_svg_test.dart | 8 +++++--- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 4671e0c26934..954feb4d3f5f 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -24,7 +24,7 @@ const Map svgPathParsers = }; /// Parses an SVG @viewBox attribute (e.g. 0 0 100 100) to a [Rect]. -DrawableViewport parseViewBox(XmlElement svg) { +DrawableViewport parseViewBox(XmlElement svg, {bool nullOk = false}) { final String viewBox = getAttribute(svg, 'viewBox'); if (viewBox == '') { @@ -34,7 +34,14 @@ DrawableViewport parseViewBox(XmlElement svg) { final String rawHeight = getAttribute(svg, 'height').replaceAll(notDigits, ''); if (rawWidth == '' || rawHeight == '') { - return new DrawableViewport(Rect.zero); + if (nullOk) { + return null; + } + throw new StateError('SVG did not specify dimensions\n\n' + 'The SVG library looks for a `viewBox` or `width` and `height` attribute ' + 'to determine the viewport boundary of the SVG. Note that these attributes, ' + 'as with all SVG attributes, are case sensitive.\n' + 'During processing, these attributes were found: ${svg.attributes}'); } final double width = double.parse(rawWidth); final double height = double.parse(rawHeight); diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 503bed3f918e..ecb0185389f4 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -109,7 +109,7 @@ void _unhandledElement(XmlElement el, String key) { library: 'SVG', context: 'in parseSvgElement', )); - } + } assert(() { if (_unhandledElements.add(el.name.local)) { print('unhandled element ${el.name.local}; Picture key: $key'); diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 43bdadabf7a7..a0f299d4e447 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -446,7 +446,7 @@ class DrawableDefinitionServer { class DrawableViewport { /// Creates a new DrawableViewport, which acts as a bounding box for the Drawable /// and specifies what offset (if any) the coordinate system needs to be translated by. - /// + /// /// Both `rect` and `offset` must not be null. const DrawableViewport( this.rect, { @@ -462,14 +462,19 @@ class DrawableViewport { /// The top of the viewport rect. double get top => rect.top; + /// The bottom of the viewport rect. double get bottom => rect.bottom; + /// The left side of the viewport rect. double get left => rect.left; + /// The right side of the viewport rect. double get right => rect.right; + /// The width of the viewport rect. double get width => rect.width; + /// The height of the viewport rect. double get height => rect.height; diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index bbbf41f1e936..5992fae01bf1 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -605,8 +605,10 @@ class _SvgPictureState extends State { matchTextDirection: widget.matchTextDirection, allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, ); - picture = new SizedBox.fromSize(size: _picture.viewBox.size, child: picture); - picture = new FittedBox(fit: widget.fit, alignment: widget.alignment, child: picture); + picture = + new SizedBox.fromSize(size: _picture.viewBox.size, child: picture); + picture = new FittedBox( + fit: widget.fit, alignment: widget.alignment, child: picture); double width = widget.width; double height = widget.height; diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index 7e622af40339..ffe641b24077 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -49,16 +49,18 @@ void main() { final XmlElement svgWithWidthHeight = parse('').rootElement; final XmlElement svgWithViewBoxMinXMinY = - parse('').rootElement; + parse('').rootElement; final XmlElement svgWithNoSizeInfo = parse('').rootElement; expect(parseViewBox(svgWithViewBox).rect, rect); expect(parseViewBox(svgWithViewBox).offset, Offset.zero); expect(parseViewBox(svgWithViewBoxAndWidthHeight).rect, rect); expect(parseViewBox(svgWithWidthHeight).rect, rect); - expect(parseViewBox(svgWithNoSizeInfo).rect, Rect.zero); + expect(parseViewBox(svgWithNoSizeInfo, nullOk: true), null); + expect(() => parseViewBox(svgWithNoSizeInfo), throwsStateError); expect(parseViewBox(svgWithViewBoxMinXMinY).rect, rect); - expect(parseViewBox(svgWithViewBoxMinXMinY).offset, const Offset(-42.0, -56.0)); + expect(parseViewBox(svgWithViewBoxMinXMinY).offset, + const Offset(-42.0, -56.0)); }); test('TileMode tests', () { From 2641e68e00cf5e24d8d2bcf19c147fb40349c960 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 6 Oct 2018 21:31:33 -0700 Subject: [PATCH 156/512] fix stroke/fill --- third_party/CHANGELOG.md | 5 + .../assets/simple/stroke_inherit_circles.svg | 8 ++ third_party/example/lib/main.dart | 3 +- third_party/example/pubspec.lock | 2 +- third_party/golden/simple/group_opacity.png | Bin 4140 -> 4201 bytes .../golden/simple/stroke_inherit_circles.png | Bin 0 -> 8433 bytes third_party/golden/wikimedia/chess_knight.png | Bin 6736 -> 6839 bytes third_party/lib/src/svg/xml_parsers.dart | 106 +++++++++++------- third_party/lib/src/svg_parser.dart | 43 ++++--- third_party/lib/src/vector_drawable.dart | 46 ++++---- third_party/lib/svg.dart | 10 +- third_party/pubspec.lock | 12 +- third_party/pubspec.yaml | 2 +- 13 files changed, 137 insertions(+), 100 deletions(-) create mode 100644 third_party/example/assets/simple/stroke_inherit_circles.svg create mode 100644 third_party/golden/simple/stroke_inherit_circles.png diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index ab44c93bace8..ffac3441bad4 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 0.6.1 + +- Fixed an issue with stroke and fill inheritence (and added test) +- General formatting/analyzer cleanup + ## 0.6.0 - **BREAKING** Update Flutter version dependencies/package dependencies diff --git a/third_party/example/assets/simple/stroke_inherit_circles.svg b/third_party/example/assets/simple/stroke_inherit_circles.svg new file mode 100644 index 000000000000..da6e78f73ea1 --- /dev/null +++ b/third_party/example/assets/simple/stroke_inherit_circles.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index dfac29a6f8f1..9e606aa2fecc 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -6,7 +6,7 @@ import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; const List assetNames = const [ - // 'assets/notfound.svg', + // // 'assets/notfound.svg', 'assets/flutter_logo.svg', 'assets/dart.svg', 'assets/simple/clip_path_3.svg', @@ -27,6 +27,7 @@ const List assetNames = const [ 'assets/simple/ellipse.svg', 'assets/simple/dash_path.svg', 'assets/simple/nested_group.svg', + 'assets/simple/stroke_inherit_circles.svg', 'assets/wikimedia/chess_knight.svg', 'assets/wikimedia/Ghostscript_Tiger.svg', 'assets/wikimedia/Firefox_Logo_2017.svg', diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index 30517cf147f4..3f9015e8c558 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.6.0" + version: "0.6.1" meta: dependency: transitive description: diff --git a/third_party/golden/simple/group_opacity.png b/third_party/golden/simple/group_opacity.png index 26b9840ab8170cea75df8479407f9b8dac356f73..75bde900629b0ea493419384a96c26b0294ac333 100644 GIT binary patch literal 4201 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 XdYpPR1SkK#3jn5umY`aFxA^}6Ho7%< literal 4140 zcmchacQ71W_s8)>UnS~BCxQgY5@lD7kg$m^dRv_c!9HpPAtH;cSkYT}^azWnn_w4N zYn8B3SMRJYS`a_){Qh`n-g*Ci&&>CJ=g!=@XXczUckTyaY^ck^#K%NMMa2Tu(=omD z?th7a?sENXRh4&X)NoVX`&3o^0&AC>EAac!Ck&Sn&fxl%ii&Lns-yKJBxiH#`7^HI z2>h;cNL^(gczTSTP9O&{7R|;NS}k=`)}m&sLRH9)%hE6Sn_5k1z*C(fl%C`#Hg<6G zt%6Ta3?Fgbl)UjUbw~<-^UF?DnW>vt7^FVniv^1LP}WTwBtw0g7P6p-v_HbaHV*oc z9v<$a(9=+;XR(v}A!U5#=*Z*G`8}QgVc;4i(z7qNHe|dlRN0fOv-Mt|CAORTu#}JL6;Ex~1*sFifT~%KqRYe!xKrm%X`bsf>2;Dh-bqnBS zX1Bo8pp!tM$jK^D;oy2FNZCVjwJ&>V^zw)gxq>$)rl!V5vb&v1?c(c{b7g1kY;G{_ zj==TnJ9YWv^-GWV_~&AIXUj`*@2F>oEvKXr#VBaV;rNaVP%!prrqP>{s-T2BYUPda zHkE2$B2GKM)tOD!eL7P3?%i+zp!P>V2$VHS|GR_cvpcP;vXFLPuivMeMNFjey6Kd^ zHUbCoSd`!F`ePC(#jxm?GPms*lkra8RH!%dD(BPXNc+2h?E=a5as z$k_8P-j0O1x`Elr=AK5?;QnbPnFyxSO)^M<%K@P5`(fLmh2V-yaH6e;zE6>q{v?;a zzI`;k-jtd1g|jm$`RdW`qZ?=9x`8!`+0Mxd)@A3T z663rw1UDhXGr<0NZ0Ku@3$FlYW+T)8aqPXgCU^jDb2wvmz{b3WD%{#xLI1Y#4E30kwga7`v_6b=-0_b zTFl2>_06=U5{v<;>j2W6H#q{CeEnEfGDTr8Yrt?siX58aL4&9ALkd^+G(3LUz0k^h z!j8!lJ>C?8|2*+Ulz7g{4kHZ)r^JyLobNqtKd;w~>e5#I) zKnm|%v(--MFlr3UNo%(sF7`!_TRwg-I(sde>8FgAsW_yQf3ko;`klX5R$XKR)x?bwiCpF4% z7v8eAHV4JT+FVCCtZQo|PHoFeU6bkOKI6>1#MX9RR#EayP2DZICdP2(ZSwPuq)5Ay zAbY@2mk89flaP!Rdw|kvsXze@gFranH)H)$+09x)F;{~?om<8j4qv{E!WbtdzwFI1 z%O2hFejg=}zHT4gKiSP#o+=U!Y~tSS0y1PC9XGAJZ*BDIp@bJKUg~bI37(5Ze@HK{ zC!ap_)aQ7P?HqqssUeR)5Mhzt!pwb*$-@o3?$O|1D z(n(@6y)+P{kK$q+0xlAqQ4-jlH0vQYBeI;%{^8MzK~u}TYsI46<0J3BxJVVW&y$v;IK9 ziaS=wFm-aq{B6J7#EDUF{ge~^fnBlBuCqD$!Rg)X*9k8RxR8dohwzMmy$8g$v6JWF z?|b+3xWqCho&Px(Uj9}p=K(lAO5d=ektYn{5vPREnZIZ~TbM4)X2b38RzLH)AzW^o zI7dhq9cC`iYnN-EpW=Gl_s~7lN0Wu$mlHqBv6)~wsBBlO3Fom}f3tS$o0T7;V&>@( zk?Nv*zw>6qT>?RU=PV-05oLh0-9D~@=+}PjG~p;pNJ~=W4LMh}%mBsD49PvDI8)n$ zT-qar-h3JT_*ih6n>C=t(^^yoPnl`HKOtk7p+;vJk_cIk58lJX1PN$tuBgR@7K>|H zM>6x_<9XaD{|KC?;PsSmV_MXc(J8|ou~#MWj{7_k&^cVld}T zKWD2m)#|c7VMd8RGfdG2QUdNS>V`X#8lG|KSYkJn0Ae@$fE$|gqt)p`qAjB)H zcCQUpT?xYe{Rm0xV^@rHqrIMWWDe4={pDBT8amOtKizNZ)=2LDJcI+hS6h-c$!!U$ z%&o(iyJf^)3nQ`4xRr$8SQm;&c(9f*BX99t4#M*Vj$o+kV!lrLA@nOyXsaSkWGd(8 znj;NBTy&w4GG=~a%bCNpYz4>G!)SCe3$DeDE@YH<)gW{Sc57X1I5qbrSujBISayo;ud~lB$eaL>dt{6FYO)NzV>Z-hGh0WdJQ(KaEH9xtR#-*EF>!R(e8;|s z{vexEaum#-%KsSrPIdCoqy^;7Yn;^68srr_;_}LcnTGp@UNg;>qE?TE)$aPYPs%%9 z)ApE+aN7o+(LN5LoBdc{7h3b)_m8XXTB+ z-e-K2siCF(hW?OvYM3_(KpTe_Z@mci(obSbKVPb@1E+S#Omi%fxzGZJVnJ$I2WKJK zsRSp;ho$Ju(tc7+hI_6yKrUdzUy2hG6bk5lAjLQj?EXm0t08NB=6TyndWh^ZNIBqz zJdf_k_)TW}xj!SvR&SxOZY6~(A?$9yNEFSdisS8BNi18rg7A4a|LfkA=9&1bxdYnk z!TNfs4X$R5g}uF>bHqkzG;GZAiXCUhw)d?G0w+#|l$5SMdgZGnRmaH$)cWhz(<%oLEKgaSTc+D5uL9 zW!hCwm<=2IH-_rK>ftdP44d?6$_ibgFfj7v2FF5!5Z4NwH<#V zLVEz$2^-jxULtlmBV}v28$D;(7k`#v)~EYaK~x4^iciA%=)&#D<43C+$PI|;$s2k$ z6`sWDN(5xV6f`lhVQrCqnd9Y)(_2Yc1wl^5Oyx<=z=enS&h@p`T}$u7gVc>`Umrmq z10Of#Owag$R#HKNrv#*FAGRd7F&;yLl`toOZ^zUg2E9PyZa60cr#2(1R9;vf;h6DB zn#ZuzL!l&ctjoAvh(*8QhhX)Fe!*;&5X!7=r;CQ}5ur$3mw*bDE8O>nF0=fhV4-_~ z#Hx(O2Anng$yf<6*1|o)GwMX& z8W=V0THOW&bog?|#U;2S;zu5o+nV7Q^>=dwISou4G9Dq{Uuj zsOdqlo}1ZX30%By@jQk-j3v1b*OhR%vP48jsEczH*;1hOBguJs@O@%-Wh6`;v3v!3 z_nKjW-L3q_BrTP1;M0)?A6H=?QMdbH5jn(2boGbeXX{PEaoc>DoF`A^kayZ%8)Slc?)yfcg0WhMZ{)A>T@OS7y0%6%a=zCMZ~H+zY9a0we5BBqW?{n!2c)9VWigo f5N#JPN-k*mLvX{?UzHG-#7_l%V5n1d9~S+8Zg~Db diff --git a/third_party/golden/simple/stroke_inherit_circles.png b/third_party/golden/simple/stroke_inherit_circles.png new file mode 100644 index 0000000000000000000000000000000000000000..7cf54afaaefb90e4aea6722dea8af5e36c8e7c45 GIT binary patch literal 8433 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 literal 6736 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 JlazVn{{tpUytx1X diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 954feb4d3f5f..af0037c6cd4a 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -409,28 +409,33 @@ DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri, } /// Parses a @stroke attribute into a [Paint]. -DrawablePaint parseStroke(XmlElement el, Rect bounds, - DrawableDefinitionServer definitions, Color defaultStrokeIfNotSpecified) { +DrawablePaint parseStroke( + XmlElement el, + Rect bounds, + DrawableDefinitionServer definitions, + DrawablePaint parentStroke, +) { final String rawStroke = getAttribute(el, 'stroke'); final String rawOpacity = getAttribute(el, 'stroke-opacity'); - final double opacity = - rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); - - if (rawStroke == '') { - if (defaultStrokeIfNotSpecified == null) { - return null; - } - return new DrawablePaint(PaintingStyle.stroke, - color: defaultStrokeIfNotSpecified.withOpacity(opacity)); - } else if (rawStroke == 'none') { - return DrawablePaint.empty; - } + final double opacity = rawOpacity == '' + ? parentStroke?.color?.opacity ?? 1.0 + : double.parse(rawOpacity).clamp(0.0, 1.0); if (rawStroke.startsWith('url')) { return _getDefinitionPaint( - PaintingStyle.stroke, rawStroke, definitions, bounds, - opacity: opacity); + PaintingStyle.stroke, + rawStroke, + definitions, + bounds, + opacity: opacity, + ); + } + if (rawStroke == '' && DrawablePaint.isEmpty(parentStroke)) { + return null; + } + if (rawStroke == 'none') { + return DrawablePaint.empty; } final String rawStrokeCap = getAttribute(el, 'stroke-linecap'); @@ -440,49 +445,66 @@ DrawablePaint parseStroke(XmlElement el, Rect bounds, final DrawablePaint paint = new DrawablePaint( PaintingStyle.stroke, - color: parseColor(rawStroke).withOpacity(opacity), + color: rawStroke == '' + ? (parentStroke?.color ?? colorBlack).withOpacity(opacity) + : parseColor(rawStroke).withOpacity(opacity), strokeCap: rawStrokeCap == 'null' - ? StrokeCap.butt + ? parentStroke?.strokeCap ?? StrokeCap.butt : StrokeCap.values.firstWhere( (StrokeCap sc) => sc.toString() == 'StrokeCap.$rawStrokeCap', - orElse: () => StrokeCap.butt), + orElse: () => StrokeCap.butt, + ), strokeJoin: rawLineJoin == '' - ? StrokeJoin.miter + ? parentStroke?.strokeJoin ?? StrokeJoin.miter : StrokeJoin.values.firstWhere( (StrokeJoin sj) => sj.toString() == 'StrokeJoin.$rawLineJoin', - orElse: () => StrokeJoin.miter), - strokeMiterLimit: rawMiterLimit == '' ? 4.0 : double.parse(rawMiterLimit), - strokeWidth: rawStrokeWidth == '' ? 1.0 : double.parse(rawStrokeWidth), + orElse: () => StrokeJoin.miter, + ), + strokeMiterLimit: rawMiterLimit == '' + ? parentStroke?.strokeMiterLimit ?? 4.0 + : double.parse(rawMiterLimit), + strokeWidth: rawStrokeWidth == '' + ? parentStroke?.strokeWidth ?? 1.0 + : double.parse(rawStrokeWidth), ); return paint; } -DrawablePaint parseFill(XmlElement el, Rect bounds, - DrawableDefinitionServer definitions, Color defaultFillIfNotSpecified) { +DrawablePaint parseFill( + XmlElement el, + Rect bounds, + DrawableDefinitionServer definitions, + DrawablePaint parentFill, +) { final String rawFill = getAttribute(el, 'fill'); final String rawOpacity = getAttribute(el, 'fill-opacity'); - final double opacity = - rawOpacity == '' ? 1.0 : double.parse(rawOpacity).clamp(0.0, 1.0); - - if (rawFill == '') { - if (defaultFillIfNotSpecified == null) { - return null; - } - return new DrawablePaint(PaintingStyle.fill, - color: defaultFillIfNotSpecified.withOpacity(opacity)); - } else if (rawFill == 'none') { - return DrawablePaint.empty; - } + final double opacity = rawOpacity == '' + ? parentFill?.color?.opacity ?? 1.0 + : double.parse(rawOpacity).clamp(0.0, 1.0); if (rawFill.startsWith('url')) { - return _getDefinitionPaint(PaintingStyle.fill, rawFill, definitions, bounds, - opacity: opacity); + return _getDefinitionPaint( + PaintingStyle.fill, + rawFill, + definitions, + bounds, + opacity: opacity, + ); + } + if (rawFill == '' && parentFill == DrawablePaint.empty) { + return null; + } + if (rawFill == 'none') { + return DrawablePaint.empty; } - final Color fill = parseColor(rawFill).withOpacity(opacity); - - return new DrawablePaint(PaintingStyle.fill, color: fill); + return new DrawablePaint( + PaintingStyle.fill, + color: rawFill == '' + ? (parentFill?.color ?? colorBlack).withOpacity(opacity) + : parseColor(rawFill).withOpacity(opacity), + ); } PathFillType parseFillRule(XmlElement el, diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index ecb0185389f4..f4762f14799e 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -4,7 +4,6 @@ import 'package:flutter/foundation.dart'; import 'package:xml/xml.dart'; import 'package:vector_math/vector_math_64.dart'; -import 'svg/colors.dart'; import 'svg/parsers.dart'; import 'svg/xml_parsers.dart'; import 'utilities/xml.dart'; @@ -15,8 +14,6 @@ class DrawableSvgShape extends DrawableShape { const DrawableSvgShape(Path path, DrawableStyle style, this.transform) : super(path, style); - final Matrix4 transform; - /// Applies the transformation in the @transform attribute to the path. factory DrawableSvgShape.parse( SvgPathFactory pathFactory, @@ -25,27 +22,23 @@ class DrawableSvgShape extends DrawableShape { DrawableStyle parentStyle) { assert(pathFactory != null); - final Color defaultFill = parentStyle == null || parentStyle.fill == null - ? colorBlack - : identical(parentStyle.fill, DrawablePaint.empty) - ? null - : parentStyle.fill.color; - - final Color defaultStroke = - identical(parentStyle.stroke, DrawablePaint.empty) - ? null - : parentStyle?.stroke?.color; - final Path path = pathFactory(el); return new DrawableSvgShape( path, - parseStyle(el, definitions, path.getBounds(), parentStyle, - defaultFillIfNotSpecified: defaultFill, - defaultStrokeIfNotSpecified: defaultStroke), + parseStyle( + el, + definitions, + path.getBounds(), + parentStyle, + ), parseTransform(getAttribute(el, 'transform', def: null)), ); } + /// The transformation matrix, if any, to apply to the [Canvas] before + /// [draw]ing this shape. + final Matrix4 transform; + @override void draw(Canvas canvas, ColorFilter colorFilter) { if (transform != null) { @@ -232,21 +225,23 @@ Drawable parseSvgGroup(XmlElement el, DrawableDefinitionServer definitions, /// Parses style attributes or @style attribute. /// /// Remember that @style attribute takes precedence. -DrawableStyle parseStyle(XmlElement el, DrawableDefinitionServer definitions, - Rect bounds, DrawableStyle parentStyle, - {bool needsTransform = false, - Color defaultFillIfNotSpecified, - Color defaultStrokeIfNotSpecified}) { +DrawableStyle parseStyle( + XmlElement el, + DrawableDefinitionServer definitions, + Rect bounds, + DrawableStyle parentStyle, { + bool needsTransform = false, +}) { final Matrix4 transform = needsTransform ? parseTransform(getAttribute(el, 'transform')) : null; return DrawableStyle.mergeAndBlend( parentStyle, transform: transform?.storage, - stroke: parseStroke(el, bounds, definitions, defaultStrokeIfNotSpecified), + stroke: parseStroke(el, bounds, definitions, parentStyle?.stroke), dashArray: parseDashArray(el), dashOffset: parseDashOffset(el), - fill: parseFill(el, bounds, definitions, defaultFillIfNotSpecified), + fill: parseFill(el, bounds, definitions, parentStyle?.fill), pathFillType: parseFillRule(el), groupOpacity: parseOpacity(el), clipPath: parseClipPath(el, definitions), diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index a0f299d4e447..10f97ef4ce8e 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -25,6 +25,17 @@ abstract class Drawable { /// Contains [Paint], [Path], dashing, transform, and text styling information. @immutable class DrawableStyle { + const DrawableStyle( + {this.stroke, + this.dashArray, + this.dashOffset, + this.fill, + this.transform, + this.textStyle, + this.pathFillType, + this.groupOpacity, + this.clipPath}); + /// Used where 'dasharray' is 'none' /// /// This will not result in a drawing operation, but will clear out @@ -60,17 +71,6 @@ class DrawableStyle { /// Controls inheriting opacity. Will be averaged with child opacity. final double groupOpacity; - const DrawableStyle( - {this.stroke, - this.dashArray, - this.dashOffset, - this.fill, - this.transform, - this.textStyle, - this.pathFillType, - this.groupOpacity, - this.clipPath}); - /// Creates a new [DrawableStyle] if `parent` is not null, filling in any null properties on /// this with the properties from other (except [groupOpacity], which is averaged). static DrawableStyle mergeAndBlend(DrawableStyle parent, @@ -187,6 +187,11 @@ class DrawablePaint { static const DrawablePaint empty = const DrawablePaint(null); + /// Returns whether this paint is null or equivalent to SVG's "none". + static bool isEmpty(DrawablePaint paint) { + return paint == null || paint == empty; + } + final Color color; final Shader shader; final BlendMode blendMode; @@ -363,14 +368,14 @@ enum DrawableTextAnchorPosition { start, middle, end } // WIP. This only handles very, very minimal use cases right now. class DrawableText implements Drawable { + DrawableText(this.fill, this.stroke, this.offset, this.anchor) + : assert(fill != null || stroke != null); + final Offset offset; final DrawableTextAnchorPosition anchor; final Paragraph fill; final Paragraph stroke; - DrawableText(this.fill, this.stroke, this.offset, this.anchor) - : assert(fill != null || stroke != null); - @override bool get hasDrawableContent => (fill?.width ?? 0.0) + (stroke?.width ?? 0.0) > 0.0; @@ -569,9 +574,10 @@ class DrawableRoot implements Drawable { /// a descriptive element. // TODO: tie some of this into semantics/accessibility class DrawableNoop implements Drawable { - final String name; const DrawableNoop(this.name); + final String name; + @override bool get hasDrawableContent => false; @@ -581,11 +587,11 @@ class DrawableNoop implements Drawable { /// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. class DrawableGroup implements Drawable { + const DrawableGroup(this.children, this.style); + final List children; final DrawableStyle style; - const DrawableGroup(this.children, this.style); - @override bool get hasDrawableContent => children != null && children.isNotEmpty; @@ -632,13 +638,13 @@ class DrawableGroup implements Drawable { /// Represents a drawing element that will be rendered to the canvas. class DrawableShape implements Drawable { - final DrawableStyle style; - final Path path; - const DrawableShape(this.path, this.style) : assert(path != null), assert(style != null); + final DrawableStyle style; + final Path path; + Rect get bounds => path.getBounds(); // can't use bounds.isEmpty here because some paths give a 0 width or height diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 5992fae01bf1..347b299e8842 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -130,11 +130,6 @@ class Svg { /// filtering used into the key (meaning the same SVG with two different `color` /// arguments applied would be two cache entries). class SvgPicture extends StatefulWidget { - /// The default placeholder for a SVG that may take time to parse or - /// retrieve, e.g. from a network location. - static WidgetBuilder defaultPlaceholderBuilder = - (BuildContext ctx) => const LimitedBox(); - /// Instantiates a widget that renders an SVG picture using the `pictureProvider`. /// /// Either the [width] and [height] arguments should be specified, or the @@ -435,6 +430,11 @@ class SvgPicture extends StatefulWidget { colorFilter: _getColorFilter(color, colorBlendMode)), super(key: key); + /// The default placeholder for a SVG that may take time to parse or + /// retrieve, e.g. from a network location. + static WidgetBuilder defaultPlaceholderBuilder = + (BuildContext ctx) => const LimitedBox(); + static ColorFilter _getColorFilter(Color color, BlendMode colorBlendMode) => color == null ? null diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index a148e9072680..77f3d0b74afe 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -7,7 +7,7 @@ packages: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.32.4" + version: "0.33.0-alpha.0" args: dependency: transitive description: @@ -80,7 +80,7 @@ packages: name: front_end url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" glob: dependency: transitive description: @@ -101,7 +101,7 @@ packages: name: http url: "https://pub.dartlang.org" source: hosted - version: "0.11.3+17" + version: "0.12.0" http_multi_server: dependency: transitive description: @@ -143,7 +143,7 @@ packages: name: kernel url: "https://pub.dartlang.org" source: hosted - version: "0.3.4" + version: "0.3.5" logging: dependency: transitive description: @@ -206,7 +206,7 @@ packages: name: package_resolver url: "https://pub.dartlang.org" source: hosted - version: "1.0.4" + version: "1.0.6" path: dependency: "direct dev" description: @@ -351,7 +351,7 @@ packages: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.3" typed_data: dependency: transitive description: diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 5ea4d2168557..b20d6e22d4d9 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.6.0 +version: 0.6.1 dependencies: path_drawing: ^0.3.0 From 02811b6ec0d791516c1b625e11b52c8028844905 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 6 Oct 2018 22:10:45 -0700 Subject: [PATCH 157/512] remove coverage .. broken? --- third_party/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/.travis.yml b/third_party/.travis.yml index bc9f40bee859..94aa202001d7 100644 --- a/third_party/.travis.yml +++ b/third_party/.travis.yml @@ -15,7 +15,7 @@ before_script: - gem install coveralls-lcov script: - ./flutter/bin/flutter analyze - - ./flutter/bin/flutter test --coverage + - ./flutter/bin/flutter test after_success: - coveralls-lcov coverage/lcov.info cache: From 4f6fa209ad26e37787c5c3c59e164247097fd53d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 25 Oct 2018 10:59:49 -0700 Subject: [PATCH 158/512] update drawing dep, update goldens --- third_party/CHANGELOG.md | 4 + .../ios/Runner.xcodeproj/project.pbxproj | 74 ++++++++++++++++- .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++ .../xcshareddata/WorkspaceSettings.xcsettings | 8 ++ third_party/example/lib/main.dart | 78 ++++++++++-------- third_party/example/pubspec.lock | 6 +- third_party/golden/dart.png | Bin 4616 -> 3680 bytes .../deborah_ufw/new-action-expander.png | Bin 8428 -> 4655 bytes third_party/golden/deborah_ufw/new-camera.png | Bin 8273 -> 5049 bytes .../golden/deborah_ufw/new-gif-button.png | Bin 8612 -> 5167 bytes third_party/golden/deborah_ufw/new-gif.png | Bin 4813 -> 3143 bytes third_party/golden/deborah_ufw/new-image.png | Bin 8258 -> 4493 bytes .../golden/deborah_ufw/new-mention.png | Bin 7299 -> 4420 bytes .../golden/deborah_ufw/new-pause-button.png | Bin 7531 -> 4513 bytes .../golden/deborah_ufw/new-play-button.png | Bin 7742 -> 4696 bytes .../golden/deborah_ufw/new-send-circle.png | Bin 10504 -> 5591 bytes third_party/golden/deborah_ufw/numeric_25.png | Bin 2809 -> 2053 bytes third_party/golden/flutter_logo.png | Bin 2985 -> 2763 bytes third_party/golden/simple/clip_path.png | Bin 3522 -> 2618 bytes third_party/golden/simple/clip_path_2.png | Bin 3177 -> 2271 bytes third_party/golden/simple/clip_path_3.png | Bin 2974 -> 2691 bytes third_party/golden/simple/dash_path.png | Bin 844 -> 794 bytes third_party/golden/simple/ellipse.png | Bin 4568 -> 3847 bytes .../golden/simple/group_fill_opacity.png | Bin 6546 -> 5155 bytes third_party/golden/simple/group_opacity.png | Bin 4201 -> 4157 bytes third_party/golden/simple/linear_gradient.png | Bin 1845 -> 1838 bytes .../golden/simple/linear_gradient_2.png | Bin 746 -> 763 bytes ...gradient_absolute_user_space_translate.png | Bin 5166 -> 5718 bytes ...gradient_percentage_bounding_translate.png | Bin 2074 -> 2046 bytes ...adient_percentage_user_space_translate.png | Bin 2144 -> 2083 bytes third_party/golden/simple/male.png | Bin 5502 -> 4057 bytes third_party/golden/simple/nested_group.png | Bin 4683 -> 4013 bytes third_party/golden/simple/opacity_on_path.png | Bin 1710 -> 1443 bytes third_party/golden/simple/radial_gradient.png | Bin 3286 -> 3267 bytes ...gradient_absolute_user_space_translate.png | Bin 16444 -> 13507 bytes .../golden/simple/radial_gradient_focal.png | Bin 12310 -> 12308 bytes ...gradient_percentage_bounding_translate.png | Bin 8338 -> 7056 bytes ...adient_percentage_user_space_translate.png | Bin 15730 -> 13092 bytes third_party/golden/simple/rect_rrect.png | Bin 2945 -> 2594 bytes .../golden/simple/rect_rrect_no_ry.png | Bin 2437 -> 1731 bytes .../golden/simple/stroke_inherit_circles.png | Bin 8433 -> 5710 bytes third_party/golden/simple/style_attr.png | Bin 1097 -> 1085 bytes third_party/golden/w3samples/aa.png | Bin 6726 -> 4862 bytes third_party/golden/w3samples/alphachannel.png | Bin 6864 -> 4920 bytes .../golden/wikimedia/Firefox_Logo_2017.png | Bin 24368 -> 23087 bytes .../golden/wikimedia/Ghostscript_Tiger.png | Bin 44535 -> 39026 bytes third_party/golden/wikimedia/chess_knight.png | Bin 6839 -> 4757 bytes third_party/pubspec.lock | 18 ++-- third_party/pubspec.yaml | 6 +- 49 files changed, 153 insertions(+), 49 deletions(-) create mode 100644 third_party/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 third_party/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index ffac3441bad4..e7fb9ffa0062 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 0.6.2 + +- Consume updated version of path_drawing, which fixes https://github.com/dnfield/flutter_svg/issues/73 + ## 0.6.1 - Fixed an issue with stroke and fill inheritence (and added test) diff --git a/third_party/example/ios/Runner.xcodeproj/project.pbxproj b/third_party/example/ios/Runner.xcodeproj/project.pbxproj index bdbe25e77640..ae33994f0bb1 100644 --- a/third_party/example/ios/Runner.xcodeproj/project.pbxproj +++ b/third_party/example/ios/Runner.xcodeproj/project.pbxproj @@ -90,7 +90,6 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, - CF3B75C9A7D2FA2A4C99F110 /* Frameworks */, ); sourceTree = ""; }; @@ -261,6 +260,77 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 24247ED7217E8F7400BE4BD8 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 24247ED8217E8F7400BE4BD8 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; @@ -417,6 +487,7 @@ buildConfigurations = ( 97C147031CF9000F007C117D /* Debug */, 97C147041CF9000F007C117D /* Release */, + 24247ED7217E8F7400BE4BD8 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -426,6 +497,7 @@ buildConfigurations = ( 97C147061CF9000F007C117D /* Debug */, 97C147071CF9000F007C117D /* Release */, + 24247ED8217E8F7400BE4BD8 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/third_party/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/third_party/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/third_party/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/third_party/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/third_party/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000000..949b67898200 --- /dev/null +++ b/third_party/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + BuildSystemType + Original + + diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index 9e606aa2fecc..6e382342f0db 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -87,39 +87,51 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; - for (String assetName in assetNames) { - _painters.add( - new SvgPicture.asset(assetName), - ); - } - - for (int i = 0; i < iconNames.length; i++) { - _painters.add( - new Directionality( - textDirection: TextDirection.ltr, - child: new SvgPicture.asset( - iconNames[i], - color: Colors.blueGrey[(i + 1) * 100], - matchTextDirection: true, - ), - ), - ); - } - - // _painters.add(new SvgPicture.asset(iconNames[0], color: Colors.red)); - - for (String uriName in uriNames) { - _painters.add( - new SvgPicture.network( - uriName, - placeholderBuilder: (BuildContext context) => new Container( - padding: const EdgeInsets.all(30.0), - child: const CircularProgressIndicator()), - ), - ); - } - _painters - .add(new AvdPicture.asset('assets/android_vd/battery_charging.xml')); + _painters.add(SvgPicture.string(''' + + ic_checked + + + + + + +''')); + + // for (String assetName in assetNames) { + // _painters.add( + // new SvgPicture.asset(assetName), + // ); + // } + + // for (int i = 0; i < iconNames.length; i++) { + // _painters.add( + // new Directionality( + // textDirection: TextDirection.ltr, + // child: new SvgPicture.asset( + // iconNames[i], + // color: Colors.blueGrey[(i + 1) * 100], + // matchTextDirection: true, + // ), + // ), + // ); + // } + + // // _painters.add(new SvgPicture.asset(iconNames[0], color: Colors.red)); + + // for (String uriName in uriNames) { + // _painters.add( + // new SvgPicture.network( + // uriName, + // placeholderBuilder: (BuildContext context) => new Container( + // padding: const EdgeInsets.all(30.0), + // child: const CircularProgressIndicator()), + // ), + // ); + // } + // _painters + // .add(new AvdPicture.asset('assets/android_vd/battery_charging.xml')); } @override diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index 3f9015e8c558..f2739a08e591 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.6.1" + version: "0.6.2" meta: dependency: transitive description: @@ -33,14 +33,14 @@ packages: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.3.1" path_parsing: dependency: transitive description: name: path_parsing url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.1.3" petitparser: dependency: transitive description: diff --git a/third_party/golden/dart.png b/third_party/golden/dart.png index 5793dfe6c124c536b36f261b2d0998a250be35d0..4c86e36da0d858d307a836ed9a3388e8b57702ba 100644 GIT binary patch literal 3680 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

-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 diff --git a/third_party/golden/simple/radial_gradient_percentage_user_space_translate.png b/third_party/golden/simple/radial_gradient_percentage_user_space_translate.png index 6e23fcd2962b3879afe8f9b32b530e3b51cc5647..d41bcabc74f62ef0d66aa4b337eaa5b0c606c14a 100644 GIT binary patch literal 13092 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 Aa{vGU literal 15730 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 BmB|1A diff --git a/third_party/golden/simple/rect_rrect.png b/third_party/golden/simple/rect_rrect.png index 2be7c734a4807436c751946e6ca138149bb892ef..b125c3737f3936ef36523c517c604d3038d67385 100644 GIT binary patch literal 2594 zcmdT`XHXN^7KR|z5ZpCO2_i)x2r8%n#fKp@A;bViLZ||QbR`&8AW}pOh|&zwyF?M9 zK|nwSq$9m#K?sH(y5KG(AT3$^xASJ)d4JzGbMKiuXYQOc=R4n-6KiE*DlP^Q~{trH?0EJzKs`#c~iAljIz4Hmz1s8*B{A8V799S#8g>#nI;W0G$>RMhZe! zQw7^+AG#{XVka2^6@}AMr@;)YVRNUjY{8wzTzA|}oVO>Sk5pC?G-B|d3$+b%T6UjA zH#Dopvlve}dkqS2yLTseS`%A+yq>K0zW)CH5=j3=9Eb>@!_FQ$?xKKcKv3>Qn(+%f z0SGAx0*%F_AA+_1%Mp|og1^$>Vl`wEJ}g*(W+;JBx?Y%2`*Hf9Z44?2+sDGF6UnD+v{V1X*w>sci8Yvp4U)W1gk zX*&P+j)pNTa1F9aPPRGy)H*h++xkqe)7^bkZ%;PzRaL2H#K0s`sD3Zz_6$l;sc!ha z@V}7r&uUn8Y#M+@UHD7_`YZagRFLnxx{F!|g)!iy`NA)~y?tCA>B+P!x1>-g7^KjP z&%;v@ZCbrokERyyz}xX6dt9}9dNETrQZ&cNTT;Y}9v^ToPlwKME572->BAdjmREMu zYZ$H@@jQv*fQmYi_4WQ+&C^Pi&vm>n*x$@VzZ?SLoBUmU0E?T7UHQBy-!~sY4h}Hl zgy%*Z?+N*A7f4)4_#ztXf{2py=s+@b*;L?Mgd2OPzEV509&Sq2eslwJ#7m)Bv36rr zEpF6$P(RU+FQA z-c@!JXDwkzxbtX;vu^WJywun|>aPNjTH*q~kmtvyX=ti<^{1d$WrFlY#758Wka=$E zVaK(TDeBlHeC%Q1QQohwElbPF&*aX;sU+>4&z$dlH_<-=R`z>i&iy_Scaq#$I=8Z^ zSn~$C&XloXXo2F*{OL2z}YGacNo8D*K{o(e&_aCx9^?-B>-Wdwa_vw{xiF zIqR*aK8kC(?B|a=ck4zZo2a$kJ#3rb#6W&)Qo^N&%=xm3L-BS<1v{bEpkeQckyqEx zFQ!)d`(Z+Za!yb^YC8c_(kdaaB1EB}QAhSoE)syVSUk-O5yLt>u zY%Rn#nMUNNvPEo%R~fB$7>blKFXlNMF^(QN=#$hJmj5H`S%SP;9T8y?sfGJ!U5p_R z3g9fPNo-Ute~5=?~gC=`oesqrc@izE)0xkuoM6 zRUNo5sSiQjNf5@GsduQ?d$#a{9rc<)*1{FFqaks<1rk_o3Y+FPC{GDyolZ?Hk*z34 z(7~hiL#n)%yow$}Y_s{dcAbMj_?Aq!n9G52>vM8$7MDd+8>Y;aWh`ZWYZ+*Z$K zUvtM#4Oz;>ws|0;P@Jn^OL*&a8BrxKoA<0{V;?2*l50nFt}#h{5eX@)1lVHYjMfJu zjyK&~ALtzRXh>pMV=SnaF#_P122RrJS1_Tgk6*Drq96M?#?a-I3r#$^5@xyEXQ1IV z*BHmgs?U5zxPUvTnqw}1k~IGq-3C2&R4kC5SL7Vs7ca@A+%3Xv29-!)M;f`s3#c9v zL0oBQ6Jqg*87$^R*}ENinko_Z;qChiLHezQ5tp{_ezJ3VPDUZaGhz>vmwq8pOTS`5 zm+k2D^&MhzK0xU2!DG=vu#xMry9JiXyNmJ!Rurf6)Ugn#Dnz6KFOmad$vS;+JLh#X zEJjl1_?B`}!SS?Y@_>@Vwo@?s3VldNLnChXGS+=M@@p4iWSr}*Hs5!3XH!bId`BI< zy?SNUN>EhhB$1;M{Rs{%vP`B`+1a}Ic@~Ff2pn{G&P^OAa(F>fr<_$oxVo8RCCr4!_fINS@bKR1%fzBLFiaNwjHgW;4Dg^T(FWd97h z?gI#^n8Lp;XX!fDgU*$HOSr$txfC?Q+-2m{IQcX$cjMPxRH@a0$uiNE&AZG5Vn_)4 u+pgXT&9j7ey;IGFSS2*HzCIWl4)BrbR1{tI`Le&~@gYqtjA@20_x}c)Ew*(4 literal 2945 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 delta 2310 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 diff --git a/third_party/golden/simple/stroke_inherit_circles.png b/third_party/golden/simple/stroke_inherit_circles.png index 7cf54afaaefb90e4aea6722dea8af5e36c8e7c45..8e892929c299c4da09a782b8f5a72095d21e67ab 100644 GIT binary patch delta 5697 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 nX&e^FP{@XD<~$(K00000NkvXXu0mjfuygXr literal 8433 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 delta 768 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 diff --git a/third_party/golden/w3samples/alphachannel.png b/third_party/golden/w3samples/alphachannel.png index bf7d6caa27592c6614ae543e87fa59a498599b12..f1a3b201225a30e395f73728ca31d0291f659211 100644 GIT binary patch delta 4901 zcmV+=6WZ+1HMk~_Kz|bANkly>H`4f5*SKV2r_rI1C(N!vxAbEL;c|7ff)t zxJV(Sa;eg#ixgMpPf2;DOPA`RCV+|*!eN03fpcJ?f>{_BJ`2SdEO?87AHthr#5FDJ zh3_-NnGd1jbaxgd>Z9MwyzrYZU%q^S#bVjX8`&pdv8ap{#D8KrfEC1IIe-U5s+4FfQ6^{%;0MC1V-t)wBmUj8Zwt1T;ihwW_B1BPp zuaimR`_B(cvsghIAc|f-WRjP~3R52|NJZipST4mQpDw8crNC$e1c8V&mhxCZO2C*% zofeDNHG}F<3V&Q&2x0QIjpZ;_kOIW9kYc%%eJ0Hi1i*M~MJa+6kc@kmdZTH4U(_XiUz5^nL986@;(5UJb-yL)tsrqM(kd%QyYyX>Uam>!+{)1vaV(;A zU%P_66Mw{}Ro&BPNqQ%Ul|v43ECyfuMy~|1X_Z{Ed2M~7H-gM&cAP^6mP>Ih`a&-R z$<~Qm)L^mb&zc(T1!1gzVZ9IZWeI`yg52KrvwNaDocE(>*IJO-%ogP;6USnurp{<9 zNEF$+LkD!<{6bqnY~7&`I$tX-1)0zLQ2?3(V}JUlTG|Q1m`$y8M91w~0SyJ2&1~07 zM>yAW08uMJviojW^dt=RE7-LXMAtml@{DfRP#Zy1xH*lbKDu2;Z3NNnm&dXnovx)8 zg0y|FKTEenkv<(QEd;S`-Tt9V6j5Ff#_T$eKC)cu5k-_2#I|+&iw@UTc|mM?)n9bD zwtq?s632RkVM{d_Q-8UF(t_C9qyMOWjjbRSsi;Xe1gd^m zmiAEfM^QOJ?AV8yaIWUHS56RBe@QIuqkrPHS56Q+Ini8Hy!KWQi!!Kq?UfTm#V~8> z1{JTpa)PK>s9Cx}#cQveAQp>CII>TmQ_>VjlINacl8EOrcJ&$w5swVV0bKX_dDj)s zDM*SG2@>$lksv{e=l7dEpNDLY3tD!0)}eucb7D4ynMfzG&FZKfr>@Ca)Q*#Lm7Md=!!Ib{hE1M zS`vnB9bJ(kef64j>!^Yiqz#fpgq=8knJ&pDFAO2TU;ucYh%_}wkRaY1`E*G(d0_|$ z1{lDD2N(6;uWa-bgmaPR+~2F&`hVDlb8)Ws_d=H8PzaN+Z4UkK;84x5DYQI0D~8`jV|aVNRo&znTiebqHqqZR^s7#fbZ`WB|(CF+#`m*@0WvPwK+U^ z@ZoDEigJPwvLh&DEBjSUQtObVhLj3XHnj=^LxiZ)x}poR)R2P0hySWpk$=?NIEZqB zcwTP0dtb%aX0rh?dv}7!2iV(3*=N)$3=B&wUx{J`DN2@xY`0T;3U^YhP9Ly-`x*EM z;O$%B^iv=S$pL_o?9+LHI)8#h5ip&CtcE~3kbO3-!w5$>Sc5xzeh8kPMCz3!r8-`^ zk|M>5+~Hp_!vquf@MWJ809EE<&1S&O4Zs*YH<5idt+P6Pz|xEN%aJEdjoHQ9^~4N- z8{A+HHSVw@H-az*+}^%u+ft%_pT8>HNpbh?Ba)K}ML1(3^?LWNw|}(>q0iTTjyXbv zxWZLqQ(3AYFM@<2@bk~F#x(jW$olPPy#MRps>zY@_z3*=n-Hakk)_8c6yxWx=J31=iD z#hOkJ-q(N>$;&k&9Dl44w;}zfPePVKKN=biN#T(F*M5NoI5;Mlba+->3c|T4#0yLl z@hL;Z^lopaZ=SI9;(967F|ze6@7@7#)abWVWmojrW{D*j7_M;D*>sg|KGhO(074L* z=|qkU&c)~Y)IjBL(W}h-G#za=95ABR|)Fnx@7)&IT*A@g2E#Ni=6Ppzz41vX> zu|F4hYA-cizx|B+Z$HUCjs1N3r2Mp$!Kk@Nx4@$DX(`PK!k9>{8boD5xRW9rXpqLN z)m~fU1~`8xt?Tr(ayDv5jVD;q`n|g)M(wY%}B8{h7qoI-LVhG zl-onB$@*iPIp&B^|7Mr<1!=hM*oG3WR4t-K-LVgaTEAWpzgqv%G)=UA>j^TScM`hC zz8bf^jejUBwoF!4vOR4P3!t7AMpNgqJ$B6?(S@LB_i)dYzmF(}v}K4sFP z2qRo<>ed&seYYe)eb&gxc^N{4l?(Q2g3RS?$$ug%ibNXC3oDGITBOV9k*8`cQeKcK z%59$8Ek0$Pw|yDmV2Tb_)?(M4vs%Ur;?AQ-MzlG~QeF^A(IeyXY}M%`#$HB`j1HrS zLsFbwt~z_YT~vu8PARV=J zkAE@tqfX{%^`fnNj1Hm*p}e(eC1oiaMT!fuxrc=+Oh)Z?(YTYUxz3|$wr_>q0;7q% zoe{Umwhk&vaX~t6>mI|WtkteouiCoDXmQPmKaQjo=KCnKW~8_vilkS0#(vb=R;5Oy zR~et$d9T!G(%QO*SfKcKxtJgdZ@+(aet*|^S1UPr)O*fVS<+NYiEj{xq)Me$c^FvX z8>1EzM4{Sa8%lWN^@tI*$2Li`?|C!{JDYD+g(Zr8r?nRZ5Nk%7Z2cN3NP~6A@Z!GJ zwH{4Sv<^8gNE9iz&}J8xXRAimjWELdF)6VuY1+tj_JUaYfM5}_TWuesm>`-k8GnVf zCp7kYVDK0<1))Auw(i)4ae@G%Xs^@RvVv5@^%9(4-8FbJ?NeV6&b1SSI4Q1!WhF_{ zH&0fO3bq)F2IdX#d;|Rg^Qt63@bvY!6v-jWhFvZ$t>__k^!!#V(6f4i; zBM9XfO+w`sJGH@~6l=dAJuA}p;ZufxxmX}}Qm_wyK>GM+vQJ4W&dHxJ{QLic|Ihos z8hztXk#5eXaD>tM9S|(B`hVpgu>SBjvQI|}-q{LgKmG#e-CF>G?9)*KD@YFFCOH46 ze+P>_M9aSei~mygDRlz%{s=$#PtdPpMQ^2^k4hL_gXGCClA>OW;PT&kFUo5%HW-p# zXH+ZF4f~LGb+Iy0c;X^j28dT@63(o7yt5VjUhw?|;Sc`(KefoFZPGVg2C` z%F06A-!b^^f8d?1;GW98Cy1_CK`P>&KH%)fUvT#0FJQ5^dHj|1dWCv_1oi$G)Qex& z7M9ZN7laU_a#4~xm48RmpTCS^_m{jd$-`-DV=KLGo}4p19zNi{#-ikUpM#{qM!|FVi&Q{{Es?a84fKp8g+* zn}E0p+|vg*ZH@k0LB3*BtPXHa9&Ng#DfRD@Zn5;3{el=4W`9X)gXvcsvpx%g{onQd zf_PpV=b|iL;>tb+b#Tr4EIjQ0uJ0Fw?k`;W2<2u)%!3$~Jsc|1tson$AUUicU$H6H z2Ag8#uqoD8Y>~df7U>%t$EYHmY>s^#Zu9zn)90f!J~Jz=+=-1IFR+5-u!6w2+SAA3 z@3<8thZO`?kbf<#AUUicu!3xHe5#3+#2l;~udsq_VFfV7u4 zCPIi&f>6+g1Ob4+tWCs%*sNIu0D!?j_8D}_2%|#(ofTvUMhars)S{r^&XL6g@jRo# zua~%HO)Vfquh76 zoFJ4M^?_1O`aN(+sZr6xhhHjs09CgAu~DQy81!QYl#d=j6+wL8s1Md>w4YIgQlnb; z{^lr4wSSG{Y!uNSgMQ?IYS9CzDv0kJ)%Nun?N{5^uz}wIL8a&c)Y*FU^3tdR?{an4 zk4cP<1Dy5aPFY1DAh^V3<^R9BAe0(4x=uOi$LPB68?|f67~_MxmK>wr=GEh|QK5Pq z`FhXMBE+a^B^0#Ow31!a-`#yOsr@H(ViIaxdw&^JHv+%}^}n0-1@V2Ox>`P?dUmyZ z->hhlapl51Pc!!i8IO%xPcV*ry|yYfYzBl6zj9l5o91qyb9H4@SL^ETT#v4n;~14% z5s*ewtBmFZq132)gmR)sJu(^@^}{v6r1X5NLo|B}w$aF_*6(ONP`mXz92&LO;{q3@ z)_-~wq4|3hUS1ltZsc-xrsld4&ogR3FhEdiKyV-J+{AM-F{&t>gd?>kG*W6*-QmM; zwC>2$-d%35u8itzUEQ6l(b;lc;QUAb${eV5-Ue5eDmeYmoKfp0swFh+}r?h-1#7i?JW>RoxGfExRc`c{0JmeWcSbmF&+n=i@7VyLA#4faq>bry{BtKtvg)qY#W7Nq;d35mCdC#ZD9y6HFRe?9>G62$C_Mivr$|+GOrW zSPbu9*Cvi53UNcC1_8kZE|iEGdDIgG5K&|{6NS71Fv2lATOk~*#S_^~Ttmh-vYEJD zjct@cO+hlENJJDv1{b4q7xOU?4LTZumrS-aR+V&W7itTV(RWd@jW0IoRDXmBbIcK; zpYK-(F*5WJB!e*_N?%6egW%xaVhjv(%&|m2-fw^aV~nM?ZOfvUAQ_B_`ed=tuj`fV zNLivY#lR3E!~zR2==FZH&D%y8X(dL6o`U3wV-ZopP+eKF0lpxpJ@r3Ej3t%`5h^PS z1;q#>1PBV>O;%O(7bH&aa)AE_ Xe;p-+jA3Fp2t6u+On`^TQ;_FY-41wfpB$As0@>V z+OXt0d6-O1LMp?CseReX|FbW7$xM(E!51W3 zmL*y0-iKow8!Wjc^}YL}>QaH#-M`b_-#+L3&hPw=Pf-*F4}TAjRq>l`fQN^b@dV=G zQ3OvQ9v(&T1mfXQ1WzCy9z~GMHoy(c&B6G%*d`{#Ha7?J^DDP>TKql~f~u;O+q!ko z+$^@17O|~cXKuONfX{RDYR}*x+`1*U@o`8d^*K*CEQGRY6GWq8^UxMgAQh6!!SFD| zVnPrjBjW$eK!1{;v-5#iIy=Sxd6bVQkTOsdQA=F80@toVDrL4st5Z`0k3SAOcS3hJ z_c=4zJcwM?(V~IRYIWW?N!Bt`dl%i1CawXS}{fsRRP>{PXbSlV)3D zEUpoVEW>A?!G#NETVijXctUu(+%j(B3W4Nu@ZpDIMBJltwr&+oE;j^1I$j{@H2nSV zBDl~)JG#5!_17U7G}{t=akM~YXW_l~oEs`)Hh&!*@TWgPZLQgs=!atkl1RY2@50oS z*_Jq)rY89FpM|H(i8!*Wl}f=o?|9-cf~hI-BC_h7m`ZV+Kr$IPejM)KH`@~TFf}Ev zc_w4FCEDXCfygqv|2~Y4nr(^u7#)QVK5*Xnl4As-DDd&eUg(IK3=YC4pNMFD~|E8~P1#Q7Lw79@|DB zv6xt##>3u>jM!`J$~FQycg}1JJhZ}2_tF*uxqaKc38kILz<_-Q4{ae3Z^Ybre1G$e z*%qk7@&cKh6ic3YIE$-S?XmufXtG9upJd9$Ohp3&a~WcRp6X$CedHKJO)Aa08bwTYJ`_Wd$-kEOP65IGbb=Zrw85 zio#e{Aa)8z@Td$c-)m1G9;RdEdw*?7f#h;tV4|BC84>r~ida%0R=!{!+GFJxq9q05 z1tz)=t2VPdfp}N~ParChWw>|GY%4sBW@yNoF?W^|$n>-|FO-MA$g;TiR>N`viO0>h zz{4!8c<(JI5HC2Qlyw=mej&0M~*ysWaOpq9HP7u5`O#y2rPX|NYpHRYN@4$8miEzyy>(qhph<9 z2}IM2bpJji5~5?1N|m1Vx_^*br>0i^I~Wu~i9{Z3CUBqoBuEe^PKp#+N-OW8P#$KA zmE{c*q=p(I%RXA*)gUS;`y$Em12H5L#*R2hYJ+diMmPf|4$hqKJp`-aX+0nSY|5R}SwqKZ%mA&7y2N8PCoB~>-gK+_ac>*in_NUnpX^-yKG+oLHd zQuNbL6HWBeODMF?Y?B_rT6Z9mA@uW4@Lk;6*~By==T{hv+~;=P42o}AdFSTf_NZ_V zH#BJOBDNY+On>n$-{KFgCqoa_RGV$m64nriqQDP7!0FS3hdV)OGut9vQG75~n`E%@ zKG{INz>gNZb;%?|8X+9UW)7f|kdYY-U*f;{9}aVvKKd--@iJc^$t0XOu{0?;60)E( zTtl*fJXc%BiK{JVJ`a-DO_n8XHpN*CucECcyA8{-)mx8-@LAJk3 z{Nd)+YFy_!$2o3jJen~AnVp5d{uKrXRsB2~vG>IEY#`4MZDZwi#!Drg7VDVhE9l!; zfJju`Js)I{cX`*aFdY2_l1RYYZ;LmbO6)9jxPSay*f#QR!E#s919)B7|J}%dgwx;b{WT7P3zPsIn< z*H5mTKW-Zon4GdqQ>%5?J=QhqR}0I?oaAK1<0F*`W0WtDR0>X?uIS`yX|J21r^(zDK=Xc?K^q5AE^$9@ zdc0Qi_6h19Ge)SVIbBh_R)6^d`Qi&h^Wq-p8Zzu$tMNh&ITY1)lvFJ@8%vK!wmflj%CzOVUraggY0B#klz%ReSPVu+$~sx4 zY-zf0xJN4|r3co;z-1%?)p^ruk44T=`m~9vYV;2=A9ix>vBVnMDgDbZC~+b0wCXC8!rV38b!lhRx5K+c94a?FBM6CgwO>jDTO^)ty%eN!n%- zNd~i|%t+m17W4C(M@2}X96OI((QLM$mP|0g80sR4)d|GlQS(xWgwnjc{U=S2>8Me2 zwP-xqZTlatt$&(~+A3T`-7~$mK=OG_k}&AW_T~xpcWN_uDf<-ex~X}!$n30Uq41si zM`+$Qsm;N3;xd<2%{p9LAj8A9Sbq7rEx)jJedRZ0x;n$W9j4N1O+F8q%HR0ww@#Wq zAgG2UNp7+Bc-q#Q>8^#E&=bc9 z1jP8r(LMdNR?tN91X3P#9W(5D{Zd&eM9rddf#h?bs{jez=y)Yu3K!ZPjKSu4wBj6iod5dj_0y9xg1CHH}`$_$U>p63Qk;$hdh@}y;JOa^E*e11B5^d;W~i;go9a* z?fsF1n}(K>Cwl@}#=-=u#U|CBKV2diHgMHmgDEBu*EF#n#_v-&+Z_dBTs)(EGaq8Z=n_$?6oFVOUro8h?jBTa}Fs3I1!}_Y8$+h+p4EE?Z@`Nv0wN z=ZXI20-gU+11@n|6kBkout01$f?h5@6gF=E31#OM2F^dpy}@p?O)?yx4>oKWVDl3f z2yUnX->=Lz$uNqAn|K0QAm^6}uA5`Wzn!IP*JTEO_!W~Q9cG(l2u&TMZ2r~vgnt*O z3*;=luAJtiDLgn@SRe*x-7}lzZrUJW3 zRdN6JV@!>9Fg4miIvLj4(&B`|Nt!xt)6_mnW5;a*QW*oFlDpoUAwmWJR)6?Pxa=ZH za(T5tK$@qyYl!BB6|ho?h9$AY$J&td0WHmZ1b-k;q-~6*j!~N0Z&RbiGI4%u)`)r` z6_Y{Xzjy*Ehnj{2H4O$uQ~Ju=q}f$;{S}%LbA268W5joRi4s0^}9~ zD5YSQfRx8C#RZHiDhNvJkSD4e9ac9xJHIlMf9Ec;s_LWQdxClbo( z^FpYuou#^VmIkb~-g{A8_Hr!N#47x%@C4#sJb^4xSRi3@JDWxmerSG(s|mX6T7)V5 ztQQtYWc3LoP9>6dSB+T|m$e=WO_l;rAWL`xSw>Bb*%lZ|GtCA6R)1I^&4qVzBF!mx zJrqUp1hRxDkOe$}EW>MJEm7Qy<)RA}%1NFl3q%LqMP95h;WE8g0B!aR$}5*Plfy(T zf!DlRL2-dZqgvWxd7^Q5IVM)cWzLx>#h-CcAj|Lsf+vuNC@zrBPFJ-@JE!Y4i^;Mj zem~ULn{9<*NJwepk{?B7YPJ# zw?Mq+)gyQUc?eG+?m-)Y^!Bnt!#VB3fI`w!lz!u}jtO z)CpwMCTMJ|#2#C*Dc(TioO{A-2!)`b!E7rGqmf27u}Rf$)d|GsgS~qzvB_5W@Ui!< zi)xX!HkQ_bZ~=SSiw||>Rp01zkw5_U-rZof3C6L(MP)?@L@nwC(%1;Q)V153K;zsx zcHMJ9yS%j()_<)t+X}G!1x zq`e(_dP>^G&a}_e(KFR#wi)`-+zfSfW?Nwx+u6=zJXX>^r8~Y494L7gJ9A*D%WM<$ zqszf%TZIFZ{_K`6kZ9CZ;V02}#F^nIk%+5C&Z9)vjDOr+jq-+04;?CNH@k9Z(1G(} zwrnxm0z-L@=gQizJb`T4;wq2UmitZ4@@TcSxvKBcM<4C9m$h&C!8gx73)R(S?`}7q zy}6lcCj>DD0+qRMXQ!(oviGx}Zn`Tz zjy5x7UVPD2RriZGdgz$3kr$}04mNK#+X};Ir+=Mic~+BSX(Nz80A797HK|Giil0}n z?6gO!Qb~fHJ6$tdFhqzW98on}Pz~B$wMYbBep$1_S)E8a#LGWzH`|Q0*}mO1FD`&T z@Q0$ws7poL*UI+o!n5TPwof#(f5gIJH=UiX%F@4|{cK~KrpMI2-hJ*l*t%8o!&;T+ zet+4**2(o|oAD^?*Sl&!a4TCY8W1dm_5$(y;m8r!blUxjk0V!hTC39@iHLrOOI*59 zq8#B!#V*~|(5L4nNpSS2Ycgd>vY(^oV0G z>)%UV#)M3i!JtU2;gUG3I_fyav5MlX)ZkMTMbY&P0JF33x4*&YsP3n-0<*y^f7^A5 z(fS!M>s+i#?+L?2?QXQgHJwz%a;v1rJ3aXGM{Y!iOa3`^f^IGi^!Yo z5^vQ`cJfF5sEfC%5XK4wKvCe_IXH6$WZBSDn}Onkb6rE6i4G$BG`iG2pU4f+)#VCt z`0?{JPjirisxu;Lh4BJeBo>1cCx0NBH0AV06N|(-vEwSqV79UY1%sm2aLHO8VZyw^ zE2`G=&;#=X0zw=oP6)BMfMhVsi5*vomD?|AY7*f*F6oT-(#!ApJz>mSp4(i3fM{l& zIU|}~CYxdevQObmcZ_pgLnx>$uh*n94f6%E$nY?nJPCL1m~Dw63^yb=*?)6`J9TR` zF~eao6VN5g6FkOa{EpwLTK&lgtRoN*HOTq%aQZZ4GG<$&JBkm^cZ_nndyq^ZxAKpH zfJm^=(cy|(qnc_Cafn~@Ytw6u4B%8Udnkq!U$(M%MF}a-X3~*ny1Ukm1{Ki5Xd4UBXH`JbKJtw zC_M8_!DQegjBtum#BfG=qeOXzXKW#iMeHSzMPf1d>MQ#SB^nhqMt@Y@;8%!h3U|%KJQy`1v^YHV}(BChbU-`V*7OjpX!M1H8;-j1z~W`;t3{} z#1bP$4t>ijArU3IB#0KAnWNdc0(qE3LewgY-|;w1PeVEl^YbgWbXx2a3W*td%ePQS ztjrXNh|%rk-xeZ4f;jP|?>KR$nI=t|`G-DfM0rDmsCwuVB1J?!^+br!K*Ne}H{c$D zczBe7J5pbGc$A4J5D$+ccmnb8D1s*t504^v0`c%D!v6!>O>7bX4C@{M0000Px#1am@3R0s$N2z&@+hyVZ}07*naRCt{1op-z)M|tzLl4hfCr&~uhbi&-$Q z=fJk-Ad*82@xatI(VRFS>VdzDI8js-DI0Y%HmXBALh;Bp8cFI3t5 z4yX-7Fb~8`rK`LMsHwEEz6 zqHH`2rtJo5(Ej>tdHq)qZBO&F?tlBglN@4@7n>>RBo#(bD(k z7i>Io2p}&s88^CcgJW|lRiXM4tazmV&1(GulS2S`A<35aLVH7{#WV+D+%Wm=J4oeFFV=pR4Ly>LeQAE#20+9a5hny7)NNTZ3zle4NWjGl1QU|2 zHE7cSsX^Q8THC(yI7FM%{EV+c$JG;S%de4C4|D_mf0Vn|hHU7OZ0M0J-yYFBCRn~h z(mN&;2n6xk&7(M7NC;%Sj`L(3QB0V6HF?g~- zQQ%3-X0;2J&J$d6WQC=3D_nd;g;`tY!}Q&0qpL3}=)r0t(PqUaTDpG-?N^rHezXrp zdtuh%i5-7G%OQZYC>wT%{OIv9mOay8*|QCLN3j9m1%{!sfPoE?JoadoFG#JH5OppbFSs*;+0>EGd9fy?8`_msg_M^_()bQw|k~O8~}M@!x&$`XMi6)I?DPz5m8Vf3Mw`e zBw_~FcnseJg;C$!-YS<#klr#-9JlL?d8_S1nPVUOBEdYUU2K5lBA9hgF-Y$Em}=kV zWze?)W*+<>hd3y@dBfFf8F=TlM4PuA(023I#+v3M6^& zw6DJhHr}lO5=glJ*W;zE1I{3_Z;<|XUIzn%rMl&(LN@Ih=i}er!8exm5d{HJP(cP2 z91He|bV? z%8-$iSa}962xqLJ&Ur?0!A=FIV>SroUdp()X?8reExh zwW$Rw<^Y*tfC4c1Si}NK4wG2L1)wkiR>UAkPMG_g=d33PkfITHh)3No1W|*Y3)HB) zDNo;$fm=EzWlvso+dmB+>MfubZ(Uf=Z-s^-Xfa_ANV^k%?t_g%dJg2UA0M*Z=Jr*46< z9vd71@buSU_rd*{p#$n-4S(kAaY`VOgio)Z(&Ig_qKAL^#zyX2IiLb=q1`B3Y_Q}3 zz%lY7_epPC=w3lnpybu{0Ofs0e8YbcL@np)m=|DQeBD~=at-_*M8mNDIj0+1cOn1} zTnBHwYafm`wQ@iJBKrp!zUjw|KfF5W9Tftip&`Nzo2e{W*mNJQ$d(-={P`zVbN>_l zL_q*SMYTid#j-NHt-3tJET$BIK^GT+CbJvq*NXz6n7SzB{5g+$n%SfWYchktV4-4^ z;SWRmQ3i7u;0S;n%V6z|aQwkJB7ZuR4XE8 zLghj@vlmVajTj_eG*BMC4#p48cTM&?KpLBNF!+tz2?vLf0wQgg@g1-K?A}Q^&Ykyc z=aRSooEyHH2L34kOvwj}UB{PpcjLNUzWP4ah#wERY|;aijlh>O+gVGi%v@*93ElswP$loh#M5~7HUXFbs5UnCK{CVRbX}K$J>bjjPyKm!|woUZNSuAPW#L~_u?5CrEn@8Tn zM|%H`<@Gb0@3t8be6E!)lM*7y;?6Av=eeJx(1q)U1sA}K2jHQ8rP3_2@w2e_YM4=S zcJLI-egnwBt@k652-B@GZnzH8lbBUN&!2sic{hJKcb_+X^GQDbsfX3Hkf4YRiwr+2 z+3}B5mee-$?pfdA+PVMEtZJVHgarA8~d>9IeuZDJ4<}p8to>bJUrqQ9bS$0Jd!z;Dgux zlr_)vcwDM@+d?T1k~7<%;>$<77G4XEaiHzAek7^n}%5`UP;-a#*<~y@ne<0*74*T?f|H+Al%+zz>%t zUAvKxL_)@CK_nprLIk0JPzse7O5Ye6Wyc?Um}qYgYo2$VbUmkK}%qL@W=vI$Yg8;KeAJ09J>K z=o4MsUq6jijbrJP-ALiT(H}qT)0{DF4KJVmumKF3f@2OWR&=$K@?nfGu z*LJ1-jzp4|o;-Hmts8|fJ_>&U}ry6fVo$~ zF+ZH#_LP(j6SAu-`G;9z#C@Xoxg2S>;ZhO=N(+V<#TEqV&kvY%#*XlI&aOI zPIb4A^aSb{&5=XsN-B^B{T%ditU7X6U~ex?A|X&?L!}17u{w zb|N7WQX=9tf@E#FR}#tWV2t@~gS1ua1}N}=z^5xyC)LfY4DyDyd*kD{fWnA7@?(z` zqo;B8rhhfMJA?|z5m}=*MPj&=PQ7N}Fw6Cn1fy&yn#L^pa}J!NpX&Icbh&;|R-yZJ z^`s=YKyy^<-%lne>T^ zdVe`(rOGkNyJ5~*s!yS@0e0{Iagiwn$nevfiI5pkM92gf6(SZ^`#G-K!!%JZXVAEH zinb}(kLf;ngYuYF%;Op9>$iW94Py&aBMWM3ht^Hj=^RVX)YBreWzsBjKqz7+iQtie z)7@L)9D2{>GDZS4Zy{O3cgl*&#T=M>x{5`5KMUjg_Z8hK1<2sjn`2N&1&U;?z%i#X z!ilxL%nHWRjS@r50Rs4q9w+bBO@L{vHl^vi2QJ`-o$n*Lvw_+D?6DM|@p!=zA0Q7n zvPl_mU(dOogBfCegnD13kbMl$~4V%C|9rl4Az~k6phWeY$3hH2{7`2Gw1C~ z_{pw|3fcn5ekMMu-pnm)flZ{REDt!Yyrv5uIL^s^X6+K@qi%%fE?D)W!8X@ zvAy*|i%5>yJ3f=)dIyCP`929$BxMZ0BrtqsW>UIkv7-H4s8pf*=zaWW zbtV9EH_LOUY{pP-ND#ljtn!cSIm2^oL!y#X;wKzmG%GJ)3s;e3YtVj{3fKqt&!6~A zEraaXqg*U0Sy&n7$jXReX9g%plvx(QW9Sw*d{6r_U}^#kcbhnUcmMe;>pwpQLr^1o z_kA}Pe?5y4bUKeU484y@f*>*Gn|HiA$7r?GK^A~ypW}C=Xj2CBET>uI1a=N7?}EQ z-zfvgXzvgL$%&OAW(W1e=qzxU23X``i6-TGdtY2Z!Ty?cA$!tS4cu+GHSRcT4nw%& zf<+p@ut1Q*Bu-GC)T>t0@em1H29I<=>MYSPMC&Owe43QE$QBvHZvhyINwepM`C^UY^8h9#drd50xUP{446=2khyfedjRc=rdku}y)BS91S63i03lCI$ zkqaE}!5~-!qmNE0i%bbX2LAk$gio$D0HD^wS!bmQQxqAu1q?if-eljI{b6q}fF1>q zGop3;pY|^SQFHdl07oa?x&^>+fne#(yii@vhMV=vUFT#O#J&8{dWiOvXA7_4?+Y+| z)pHtaUTY)-r$W!WeT|+JnRI{*fBA=ueeVuSm)MybgP4UrgSP58;IQ`LG5)gUK9=$^ z$XEr!^m6@8?W??|vW%<&I8R_{=+a7d`?T>TMH2u<9Gp{YOVd*DCo8V^8@&sda0Tjb zY(16Avc;qVBkyodxtIZsDhyA};NheKq`vw&20!w}IA_EiUZXWLtr&a>rkIR!w~Zrq zK;9nJ`BC*+-rN4&d=Pl!3m5P z*#ObbeE^0p>oIOiRR$Qoc1xqY3SlPt{i>%uORh&`#9j~jBJ+*E|tL?01 zF+1ep{Cw;pemwMQw$zXI0L23g?;p?@pmFPrjlk$|!n9}1Uc-vlye_`$&8(susxKj# zLX(mG3=El9CT(@p19SckrcK_Phm!)3U2pvx>JKibnt&suVgWef}t5Z zlmJ#P(?ovu2!ICUO2 zR(#>p7v!S`j7;9R$UXz4_tW2rQ_9$EJ9mTiSn|M-G1_?B{Z-cu(6z21nj4fUGA9il zqfhI+sP=SfJT5SzoU{cJ2Q1Y#_3?;!e;Wsn<|8Zr)NWhR5^jZXqg^+fX|22zFq-JC zytMPdOxXJ`{{2rt_6Z<+Klxo6n|Gm4I6E*HOCdWHS)OCmzNdUq-Q43gsq1bx;`z3f z&+y%HmuZ?b-~LYsnGdEskXX8SnKmO~5JJH}uKXjG_nhi|_Bb(%WKEM7wq^vfuo0>N-9~`!86B6)-$G@zmt6Mjje2_F_4Hra_P_G9k zLA%mldFPi{H?+9PNjVa3gRw_YUy3ha6W@5nQ~)7!&EmWO#`Y~(Zy6v%_dUhv%8j6b zk>kU=Jz6bEX`^?_3PF~$pCYiBx~lQ@baz+2eBSB14_g6md-^l1>OTRh?POgB3P9q< zCZ4i{LE^I7H0YRae92F6{P&hAkhH=iQ4fqg3UbsrHxHY%8eg;uguFae*!3~?MOp?( z@3-#FbmG`D0YDUOUpn@1q->Dy9xG3}>yE<5CA zb=VR>!oFd8zjd#N9pbecsAK2z-$ySY`bpoaly=<;wg<$_aa-?eiubYzXRY*ovWr(g z_3wOX^Hs`FJ7&anOdvD?NwYB!6EM;N&$L;pcgq0T@!!6Sb%Q0Q##`syfbmD6VSKG| z%Hj(ruYus^^|hB0f;JeqJE!r@r6qv$+;rcB?aV6^Vurl!iojz4xY;rD%IA*e6kr=r zvUV6IUO(TM&1ZVw!GcHb;I6&rs+(Bth}pvjh-Qlm3X0joTzAb@E|(;Ax4tz2cS{2G zXJGtEi0bJHPkMae=JDsHli&Rx`S-4gwDk7}JvZIwFDP`mpwM{B3=ZZTb6;7Z=`l=c z4`J?D^4hJnXA`Y9 zVeM}+^Tu)OPv$hZxs+y*@lCrKUAd`gJ=<2K-@Pi{sH7OIFcFyuz~<+C&(>rKBV89& zeifa_xf{OBS*yOmSGHcM3?`B(bF@!S^Lj01%m5~nIBQ(JB;!W;*u#xeq=2?Am^KH{ zUBHr4zx7kTwc(9^w!k@Ga|s7w>|qF>H^5;so|z}j7cqjBmnHM0`Jf%fOMXexk23qP+OS&e>;)1MoY=3a&{*Nr|7oL9aBtVigeb%I90yaco|Ec{VwON{xXmBpKKU^ zq(0BnIa3*C0tgRCN`bj1@I#l~xZd@X&+^Ytyr0|=ck>#UOVog| zRcby|>3G7;OMgB&UW@rHe_MQybEGst`fgLb0Uf8e*k`^!WPgHdQT!j|o@c7fIkpi86==pX>!dHRh+Ljm8t8HX9)$L=>qt0kn5RTeotne5~M&KRj%beCw(VbL6F^ z-_`QPEM0RHqr^<|y-jc6?&asf4q9gtISQjsKz(Pb%wq^EFLUy=o+p6kTmPs-DS-6e zwt@x!{0{nVd(2y|nqc}l!YOMa6Eak%8?{y07eLM&hneGiW%QL?_}stn#LzJc5PCr% zYF&tq?s)o$%mN_+1o^I&FYoQ@#h;ESsHgW2*>MvAvI1RmjS+Xaa?O_*f3^nCG69e@ zVC)$fd#=FnCjkh#ZWge&^}mvC3Xq{Ew$Qd{E;BDbi~bydm}1+V36z{bq0mqZf(!G8 zG!>`oQ|6SlAotH*#C6->M-W8_DHGNRDxC!F-2_2R<)bKT(0Qy;1Ppgcj2$unh+KVM z-qkrvwOs}8G6EUVJ2IV*g?|VefJaf^nQH|k0QGG!`V>iAg3}gX9$&ry2yR}d$6KG5 z)f6E8_dLtde|pNq=U&NXwps*^77a8P7)|z57Eo@ToP2NC6*GoJ$Pgif0!Fo6 zP2e;bB>_opKu!)YB1acxxA(bgJ}`K@kbV2YUZ%~Cw^#f4=!!q$nX{L`F5nShi0n4a zK+@O?BdcPN7!@rLIOmbc>tmDv2Ju?>KGIz*O#w2taW6Aoej>fMK2DR-jMk*p9ZAT% z*3@*j0RR9X07*naR9b2q-?8?++pBLZeX<5YjY``L#~>PXfI<1Z%*%VuPf9f&(xMasq|rOV zoHwe!^6I-S{rg?%?FzBmZ%TTt${40o$7|p@b**h$0D<%I1ZzJz`9;%r5JZwdK&9I0 z1%wYQ8K%e$$n$_vuw;w^Cyl*dSD&|^&TbM0iz1dicP<;}9tFn&Ile7|dwN}qFi<}7vir*zxx4QoP&BFQZs*yLkP#IE1k&qPrRgxE$HyjlEFz`tQbmym5RqM` zfs+A79$Xw zbbn)g`S(1QQr)~3dpMGQ4$d*$bX6=FBX{=Iw0_CDUQjr7ed(NfB6)f@O0kCmNvHyP z4H%bA+OmR0g4~L8+H|cX|fbR`tN-f#TX)PXLbxiH6QZ$v&H*|| zt!X2$4oZW>Tt=URaKJY3Lc^y3EM#?hI{t&7giZHDy|`zq)Krs!`<|s@Kq);}0{}8z zC6&y)BNCC{Czcp*-qtyFi>k+s9vbLmY^+LzAZ%0!>j6O!5mY3dGe-~sbR9Lon!yG1 z)u(a(QERO8(ele}rx8RE5#zD3D}4|_6f{puq4N?5ka{Mqo@H!3y3B(+4Uxt+$#nL3 zZO%qPrc>d~ym`X}6h3@vT`)eH+?ShIUc$znBUwCqJDdqT7PniXn4}6U%-L7bgJ|Sg z=r{?2PNUpFmo(Qtoiz68=mKE#{c!)M)cNna1CD-a?kP6~$j}p8v1W7Xi!4R_0M4>S z0-m_O3z{?=gT(ig$%sf#wkd!Nz)0xp>!PQ>lab+ekb)qHs0322g`^Th1c7Ad;0*q= z?-K5~?+o60!u|Z$Q?KPEM?KATXaA7%k9vyD1BdZs?-E|K7QonG{`pb@Afp@i#;JmT z7L<6uyqP3K0b^LI%*;8<(9;)&e2sAGBG}VAjh%bCX@nIjK@0>TsUQhZ>xxiawX$9E z+iQNG-SuvwAmFR3F9Q+r(6*DfYWs(|?3l;7{(`U5T^r)EAAFpx{qqn)#SlWO4?464 z3`t~6pfkZDMIJZ|P~@_PlLrSF9wx!e7f7`;1_+7qEnE9y1rUJKP$TS`MIzuS;AH$D zDPj>q7+wd{PC$Jse*(+_23U-p@7-ct#~p>I+U{b(#F}##p_|vzz9#W!qfBdW9;IY7B^~P^@9;kbG#v+u1YTl^DDkBLoP3w*G8h z^ZkE{8Bc=lwnY}k8+Kj?>UO!(>$+jmeVq0h$#iKcNY9BiGO`(x5g6HMpMU9Kyr8_T0wHRt7raVM2?puAXDwOoR>q%z zMfS)c=TmEExW2sZ9LlErhjE5*sc3esu(`t;VI z7{>QVE@F~KAB^vU+Pv0SqDVI@g01nj7%;khJ<=2)jlNOCKGV2D9Z)3hlXA1v9now< zyw=-lMiJIY`lOj_<$^{nBV#qz?U;*z7!ewKWz!ntC`0jfVNJh7T=zxlTpG2l>XaWqQ zty(9f`p04cwB@`;9ZOReYjDNZ7#J}_7zQ67&0fbw=7Pi&Z#QqowQ}n?<LF~i#~RMq2FRfN+2V)sdwTT>AMRZ+3rES;_r&|d3OAdF-(24atKgo&%>2K zWx7<_?Fx;0rY_8O3775yE=n7^vfax;o8y*6EZ=;BeXACd{zYBYNcRJJzN>pLixz;< zEfDE96XSv+m#WCkicmp%2+SxREG%S@(TzRm$593pF=I%u-7J0bq&DvpD`-zDIZTlW zyiKvoHtw8*h)}&#NQ*%dcS@Kpm(uSMoodhz;)@v3CgN!ofy(Qb|Fi^AKwGtgFgDt9 zfw^V`GdR~SmCGPzT3F0N{IE(HMPj*IiJL{5hAfkqy;(`Qc^`5_kA)ad=H;7@x9coM zv4y^GCX?(!{Xb|Y#jN4x<+vIJZ#yC_Xq7p%PQN6kZKyzs0kWaTuuUWOkQBOEN&UE< z1ult!Bg5rNo)`u3h^MCtBt3(j)W@nS<{)*QDh?QQS>j>|7!Or9twbOsR78ym5J~N4 zt1g+q00JnG5LA#&;}4zJmSTd%28UTk$SgQgzzBpiT`%Lh3b1>yFxG}1X+P8~OcWVS z5HoG6=^g5_t8@U}z<{wk-A0L;v$ep`6&>2lkMDuXbO@%!WgdW-?pIRm=pv~Yq-!4m zGO%KsdRocY_+{4UGt3gN6TLQM;jo5v5jt zK^{w3-if1Y1d2sE%t+(PL47E>Hob#g**b><&yn6UjI>0(OVR<<>}#CV z%gf7A7~c!E*>S!F=FkNLRR|??G-r^eLAnIyTz-ZD3_!b6nkme25$Oks29?>Hl^no# zLGprji&+HygPlpRtztrR%)_8B%J@!>1cSF-Rx-29Ta*>*-iDhpsb^PF$?)ghewpiH+X?kLz}6$@F9yMxTms zfTEpjC5=WvBOVCU#&7jfA*l*7x{Cha@pyUX{Ku8yyDvLwpm;!{XXBd2?E=Fc2rLT% z7d&nq6BPMNwvGmj1)7$6#vE|zoCBDHuMM!XK0WPD)ov4UKbE1>B>|DL4*>+}x!HlaBn{4e zV;p7OD;=1dfx7Ez*=Z5q6CqRgORt5&`nE?~!o`Y0^#q5+z*cNJmNOSVXV>e-9+SaH z>tzV_B-i5eCVc674^(ERZlo^MX-j9?myB`}Z!zzG6hULKoJ-{{VeDRYM$mm;5d?|>(!YEMhrQ`E)vlyB%Q1LqgC>nJ1Q}3d zK;Wc(bE~Y2WXCQt3}P@u2`DNMgCV9pbCrNX;4p^Chf;!0wQ&>l2}9EEX^`P15D-Zb58TgU}3z!9! zd-#DNEHLOYVcd`8p_Sq~VY3PWGUwu$L9`nc_cEo-VY7%i7Lo+!#uH2%RT6Yt9#ed?tboeH zCORL9WNgC@&QXDQ;zE%E#dNDGr0Jwg9se)Rxr0;Y?c|^C{Y^d5M72i)A#qF-o-r8G zW=j>Y>+y;5fw_-0{No-rV`!ZV5ZzuEAgO3wJ~)z^%&luUpDap!qp80&?#Y7+)dn(_sXM^T!8d1-@%-iL8`Ml4Wl=h!~>MHrwc5%EOD2V z&YbapnRa`yydY7V=pbAV1O{fDk;fh;Ad+CwsTT%Ze!`=y-Fp<@U41Ef7*R>=b_qb3 zgNEiw_?W`CHi1y&UZtQ=V954lrC`D8#Zs5hWDFAsHbBaN13)@GSZ6HWkPi^e3g+d( z(3$st6x+>m>$`ag$cA#YMAd4O7c5BF+6D_7iah|PpO({bCAk3UUV225o_^+0R*;?q z>lPs5*h7Oxnold!Jxdt|JaI?@67ysomkV_xO&3d;1wNpdjN$`@2`D5;!L=9M!jauQ zeC4s%GBDnyhzosAu_Uj?X4h&!TeF9`&c-4sXx#4HAOi}MIsERG$tD^I<=DfP?BiV4 zhY`~39+fPayE7jk`r5h-V&?U|kDM|*d0)CQ4AmKU0pYq`0|6`^O951!nbUA3rT?SQ zWDsrK30Q=&j@d#_cd%V6D2hW=slgVSJuvg?WYxq%#T+&>7>CI$KJZ{Ojm2hg)#>;0 z`ja2#v-iK5+nzbkai?SqQQNID*LH&x5R@VN0(N(vRcqrOraR^4n*k)t9zI`45`}d{ z9Dj(|2+v%&J|7^USj2sC&&Mbd)#d9>Kgk130+2B^iO~m$2Jdo&UiG zXys2lJq(f`hZtbeZV|E37-d4oAtuebE>$LAS2}@6d#SX~<$?nYFc|D1;tOWR9wt!q z+@+W@X0(m)x39Q~vll$eXYP9|1LM=;ePy4*nRRS=A~F8dctLW?{EfV1(UZJn$!fYg zhnUeh#HmL-$Ag>C00I4D(^8e`DD{-lSI2)^?0YuPq1 z5Btj_J{K!y1%pkFp1F&27OvryCq2R|Pkh+uSu@rW&R_UMqI>np_j8^2I{jnQ`QD0G z^Oaw{h0T3Okae#}bS@B5P=d)MDYN)4W>&(nK>}&`LQ?Xwlh&l}k)L?{01`QRU;Soo zR#*p7iFFaf?}xycFl{Wgrx}w7keL@9$H0BhWSGPT zMAp^PPk-CJA_a!&Ud4K0o>(4GDtbHfYQ;O!MxKdD99GfWC*8eqLF`&3`_bLIMkm49 zN3Z4V1#2PrCeQ3Xn!)-s9^HB(QV32wdUAb$7Cyx_iIJx^p*N9ZpT#tnM;$xqn^U6w)em;=%{B(J{rA<~Ek z40G5+0!P;E{G6A08evOmfK+F8B4v;hhd9ByFK~xsJSBOmq1=$+TrhKi>IK zZn*0=x#6zgvf>Y4H?IqjR@oyQA5;@LjmEv~ojqtQ%ikGNd*|nE`lTW?*(@p1JhW|Be%36Mg~{Z2q3a=_qo zv&^TqWt{p+E=eOy^GX|3l(f#CfEMmG{<}N3?Zl-h7E{o`P33%Jm zJ9+rI)A*mqUWFZVwC-Nz4H!n_{V{{6!q>le1v5KG^4psy&FVM1Ccd)B1V^mQtmBQO zEahH73jpap^GM6Jiey0G3D&)UvATV&pg@5{7{R&aW?=wB1BKLR1LNc|cAJ31H~|q` zc!E67zLQvkbkU$lKq6AmneBDkU9|SOQKl|0?aLeTH?RLP53M_mExm_N*uBaHM>wVe zVbb!~pS_}a{GrdW2ncQ()E|WA)%9&FO^Is#4cTq}4@0($i)FAaSQ0*GfMu%`&gc=d>xWY@&4;n&tOoCKjkysZP zWBd3~CuN1?_0TYmo`vh=Mj(udBqC6GGe~#cFR*W(xh`8aQRc8_7^iaHF{=oo5X~6= zX(rI>JS^p2rI!ACuU?il?mPw=%h4Axh&yqysD5&N4TdP}&AL3NL0M@DAT!Q9ioSc+ z5x8-P>t?y`mB-C8Cq9~8lA3E0pd{>}(+*gKQ89DT1R{tODTMLxY$b}_ISCc@m{MP7 z*Vbk{o~3|FnpZX^Q{V)~F((R;qI4Pe%7{YO&XL+ivY3RtcW0fiO3mM&w#{a7b7?~ zdbH99vVEt7`Q-M2MUs8=Nh2Xq?~aRrMx#xEA&L}GWF<~Z(!W%T%c7W_P?RiWgfu@` z5JZS-OxJPTW4QZvFPXksd0n`zfFg%E0JiO&$G`pbt#PkY795&I(#w?s!_>LbNP=@E zSH1iZ7S8P{#~?0yOu`&Z-7IOQ)3UrcM9*0D z2fb#@VARpQPv(kkxuSdbp?Z??dpL5&}9A<_<>;^T|j-T7hy~<`LiqUZ0-VSspsgM0VRGmm10_* z&zp~B>K6Yt)bjq(Co3%hq;ttErk`;n!z;HWZdPG$mID%m2NV&VkzN=BNY%@d=i&*G5mYPfD)ztzhlsC{xP}uWN#Fn|h?yuzL6CyM(8Y|BfTbeiZ*`^lor7I`;^!~tjwer4Zc-fI z2_dP78X^dYq$HFLkWdL~bXB|6r+9L}A@p_CtP)=iH##?MuHG0XtPdrZ`uca>PIt$s z-*}t#V3h%dt80Zpkj4Yj0EU@9;ZJiKnJ+B^7;w-6Zy zG2;@UPuyS;Yh>ML^ohHL6VO9;Bs{It)w!F_X+8AxE@F6O9tdUpiNTv-F!c^#6hp*$ z5vN@MRAgE=$=l!=ZdAGP@zeOqgJ-FjECxm(1Ra%Wv{k1Oh-&%}5rR-g1c7>|Qv2Xu zaA=Q1mq7xK)Xvf}DI-S5cBB6q;6=WWaCkM_JO7Jj*Z6|{BPE^ zYQ`Y$pEs3Z47aQ-K$4i#0}Kfq{U+#ILaQ<{fLwVB&)>2-ajR4;62~Dpafl3%$Rt>g zq=;`wK^$U$!tC}HCMewLAr@e8K;gtA9`MwvBg{X1H6c}cdls>E$BERaCIHC-MK58( z4i-p)m_;Yk z;80)?=oi#dW=J9qQl+^PjEBRFj;H^;^dEopy{v2H0>WqfzWBpeKQHZLpj-waWf0c| zl)y>X<}{>OCIpbfuRNJG*L5NXh7uRcbhQ*XZ1#wx`gFf`8*+QIP=HcI;;@GW00$Hr zG)+MvoxEMI5;T~5*g75<3AyRXvv}>?VNPnV(pm40jb0ge7BpeX9+uv$D`^BFYexl7 z^mTFT`Xkvp8vhTth*T&p^KrMXVa40#6ebky2zXzHkk`DJb&YtNgX(@pWy7)j z>&E%Xu`if2%Bj;E%&)=G6#vi1Rpk6=>vwBf}boEhSyLLd6{eW4j=#BM`jpWh;5x zg)42>s%-pG#2)T8zO)`BECNX0w&q#_r(a*tkYW*1%A(WAm7O=QVfkCWNhN4d4I0T> zrz=5&iU_F$p|NgI2|@y`6Cr_!2$FSV<%LlH3?+zt_jpb0&+D%tX4g@U-nWjj`Zzrh z*0|!fH_~5kORso|tEJ{M>Hs)ii_{P?#(boJHc?|*&`FzUb7tR~+knq^V*mgd!AV3x zR0?Blm#5<*!U4${Hs(p&E~+_xqRW#uBN(XfWwbE_z*}FsicehgW6bK_be?Vin?YJ- zk5&Mpzb{~x>-GGL;j(3(gO`)ivw2-P{K}IFW_BV`?v?Jv(rFcY1gSeE)zp-<+;yw6 zdBE$A*|To-n(XXb@7k#D;AEBsQKWRn|Ah>W zJOvGaq_LzI%GNbYmsyJHpD}UvfPDZ6z>+_` zkSI3bNV`12K|gSn!Mb}G5R@P9czU8g{C0Aqd?-UNyUMxs;t!Li+pH3kqe z;;k2~;^XhWBl{r914rapMzO(DWXx{f)#sHL?L!}X{>5puF6 zG*A~20V)oOWIRBabos{2ASIE0qGFDT#Jycku$~*JYmiJd=7@KZtP`Eg=q_KZ{%r3H zzj`HIw9yrpheU)(>V$gs6Ah`-Z6dw2H3BMBsER6y`x6PIF;0}8T$?>VT_4HQh}fdBze6g zLO(4^cj;mS!3UVgh!sfnmoHuq{G1z?znqbA^}*Q+0TrN)id8pPWMmn=je0*Y(w&;+ zCRniQrEeh{vv%Xy!=9`NeT_awL-ir*|9kbFyye2D?4H5Apga#80_9%S9eo~Hia?S# zi`UJYZ86u!y&L8%%{g#+nQ)M9f*+hGp z?CYg7;tZJ+heS?!T0i?Qx)NWkV(u@9BEoQ-z4hIUN29#zjCK6*!{6bQqjzWHh_W$= zscTUDcWM;m-LkTaxt(sused&o;DAX02*3%~UuyMaS!>b>jZp#sx7W)zSeOR?QPO)A zAJAPF1>!9R1xY+pR~LrfBBZ_x$+0!P%l z5PR-bGpj0co63IC#2ow3%Y6&sH$DPycu$iCl#_i5(oH$x`b$~$yWfwelmy8-h*?C$ z0jkhJC_xgS3#mf$D4DXW-!pLn_jLFa$C- z0eN14?n|3ecHUK1&x7i&+R z*oDjyAycbxL6NRyTvss22(rD0H=VnN-@bUY9~gSGJW$}#xyC9`y;km1-zPqxxWI@! z^?Z3@)RjO_JFJ`swFnL?{@=k?WYSzLfGsyJXVve1pK1`=ZkEt#vnQ(&_hf0;%5=eE zmx^qUmT+Ay$K{$(?^Ka%m8bLSNz#Lj8o%7Ugu9+Sg_YYUk5&AVx>iGSjI&OCic4R# zo>!c{kr|!iDF`5&E?O6*bzV|#+(SzV-c&%H;F;wZeQWXBiVeWo7e67B?3XV``6d?JKNZw0UK9FeL z14qEqvlTdI)!{2Yg2Rjdd$6obIzV>byoSf$a+4PzRbvuk9x#$I5^un62kp6IBSKCL z5MFTL2S!M@mzjs|4hfqOCndF6t;}2oSBT>8-c>%jL;t@c93DFW6-@h`!ceB78Ami&d zlbHW?BlTi*s86reS$gDlmL9du29yD!M>ih<0%mlMapDnsY{Pd!5IK2iT^B(7fK2Te1On5UQr4m~Jn02c zrE+exe$gt^^;^0dw@5F2%JSj^h64`kk9W+!R=55f$Z1Y9VBo1k&f51ZFoWVESE!8m z0ADos%GAa68uu-N-O~_6LTz?7MzV;Z=z>s>@%Rqre z#$X}Hx>Yjmky2@a`U0EJ)k;AVh{ytoFrT_!CK1`EUTJ_pbC7t-ORz=;5O{R%zhe2^ zDmP!2J@Q;DlQ|~h!8CKb+^*d`fW*fRpE#0m&3x1wMj(zFgmZU7=aJCe`iB{cWXb?i zo7KVTUwsS9-||gFpqL|y!6Bl6D5zwCkuZrFli;{osMy7DvwW}S0%<&AG6@)Qh0c@C z;&mk#2PKVfWDEi9>hXjI{8ht=1ViTV$T9!q0d&6?4oH_rZGM7E_wuyD&`ninV zcWmNM$fE`cu2`$?-|2tQV&j_2lmP@(z&`JaQ`vLNYCA~B0E_Sh=<%8uAf~I8e%c_t zzL9`{D4hnL7mt8H)<{rfDKg2HBrg`RbOnHrLIv&`6uO>1H}k*Ui`b+rYZS#Gk*Cf? zu7^*`cI$?MsCOEpKR+2{KqR1gWIwgbpH>D?X@~Rv&jcHnFH;H-fHQ7RLdZGy!cw3DYR8)uYsrSkMeu9Qz_fN=IY5-F^;VX@^&3{e9%^tzf%-I#2@K6B$kP394>%ld;on71jtA* zc*mJUV{HU&<4n736_q3U)Sn^Am_082mkBneSf(5xpj@pZfBVJk`1&JBJR+ndiUNd= zMI2WPw2nj<8CT6@jU*n4$4M-oN|FTa5|JG`X=?w5Mai5cuS>TqYk=cYnTL+us{{}f zr-d*;Vt_@TYZ=$dcODpZChBIH5|Tds&0|RWT1WLZ`fojlaQAfD7ww|!(pBo4W69s* z0attlIwt4+4_EdJKmbm;;dKnI*v9b6tw~Q-i0;*@AR?*0IEWjIkmx|ONXi&syX_GX zfjjHhWE8Li@`=V6iR8FrMXceLXV}663ack82Q+#KoV*509((9@GZ!ik9L+pZ-!=`y zz>_+5UWQeAZaoh%T4m-Ne?@iffGQ6)hy)yQI-GJp&C+g{#U}W{Qp6%FdSDp2S(XAsMgcu{y_l{u*U@qGPNfVD*9!q6 zfZw{a#DOO+`wbwV1`tpBmpAa_HUFdHju;$a3>G~&h;-r)3m_zViTdA>)V;Dt+0}Oq zJUv?)WBN0s`%WYI?pC6UjoCE(RzQ*KQjs!-%Ouv~0Slx$ut8v65<&jBQLFA&C=@^} zV32XO8oe`^bI~K|HfCI+0dmFXrp&d{vR?rLaP-w@F|cAgTRwMR9HhHUq5(o0e;DqT z`iO~+M_l(RwI_8yBLbsm%Nj4yb`i#zrXVSBrSgE$%%w`wF?jMoVS&SC4RU~y!y)|Jn(TLg0G#}p*E6!A zhrPG1QlYlNBm_Dz$9Ahc@dzj;Fr$r0sEH4z+dx5b<^}7-ttw!RAYROwy-6LDB^*Yoa%9rq2Wds>y`wyI_P;WoykKR1E6aRuBuZYgQtygH1evsYiOPL{M2Lt0 znWW8kM^udNyhl>>PDfsuXreQwv3t|P*~ZjcY0`SWGOf3CPMPUKX&t0_*S#|HiB3yN zMhSu8He-`A%wg2iy2FlvzgXGiV3R8c6d(Wt%eV9BEB^yIFl2$Fn!HHWZ~zh|z)1iS zmnmSVDU4Z=sIqb(p*%o*^)n!FfY1ySCJ0IarC{v?3#JY%!00kOc~gf^mm@=MX^`Iv zbLhMT7Mu>(-QVOulP?DxAfQ0<*ekyjgT!GG>z(x|ecR9ki&5rd4U1LSSCHTsehwIN z!O;X1T5p1&kTpDO?Zy>>g(hjpVGze$TyVJgk*ad9@BxDq2wLX@%(-uacl{R!LJkUm zKn#*seF+8zGvG)+@L&KWcCGBR3zC#Iia-KnKmOozoATT#7XXETD8nG+gTV)mW^96Q zAC6w9(Pa`pKzwy`WULa$9S#VRwXldN(_;m2*|l)_M+y!ywQ|q^1Ylsrb{>D_zas|* zEpSxK56d}jRtgH6MQlJAf5tOWkmSWDF5B!6_o}p;<>+v982iv=RtzHTb+SEnJ`tl{ zy`p-p9Ca>pm^ukmYw$Z?g0tSjfs}&^AfQ09{FPr!V-gc6$tQtQ=FowAn)ZE-(E}1s zOaeAYwCgn?7t6;W6LGIxpcDebr!&fOgL6}F)YFmx#M~F@_O3Jn{mJH00J>cUiC%AB+lQrRh;15b*)+jiTgKi&`yr;0Rk|vVjHX9 zb|dx8yEFfH7#M-O4-_V=WI^J@Bxc?hu#*C&X^&O2ZrllV>6QS7udCMwh75B!bzH;u zg26Bs7f3#EB*ji_;ew`nHoX7qaQp=&tYiPlK?@LoM(+sAFZ&`RD>r*wEt5qe8!(0| z=KCt+gh0|PF4;V6iC**_uKT|`b5kO&X?kyF_Kas$+%i3U{YYXZdNImD+3_2+(_p!gsCgr zi`8myo(B>N^5#CwJW@?vAFpNx*e&Kr@9Hp1Yr07u43)`zM1I;&c+`;ka)U)Gt6O(n_#mEkQ0|sJ_s+0Ia(e2 z@ReigJ#}%@=5|K8m51CZC81DphtGnfQ&|FS?eL~+;f;Tudyfw``LzNFz~G9lJo~<5Vn6dlm(FUI>^E0aZHofDS; z{3yk{8Wv7;OKqbx`lzc zp_3H2ROyC;qtjV2_;Ox)=Yg3&HJS2j4G@5_jeA-9dtd*5?VV3-6jdC@KQmhjlr9Ps zt=ozkiP(71gccJ+f&ukF^nj5&Mx$N~HzOt{9yD@LV>}?9l!Fux1{0!~aPS}2zllo! z7)eX{Q>5)m%WnVC?(B?*-I;wm^WNKS*|PofzR9HT{od}Rd9$BkA}Aiw`^bxAab@&2 z`UW?1&1q)msn@A%-Z1wIyFj$)0r53*;tc&Segb0?p_lLoKnU=JU(zF67f}M@r(ET@ z$!x|PrPe-zHlnd``V@v`HqH?S#eZ0WMAMmCdj7qe3&}gly0zF=jIHlH%ci{xYr$`> zS~7qDIH@W6UpPYgt3M=fs*;1EpWX6`9YqF?&P@bpZfNbJtTam~%T~|{eYPy;@Cx^Z z3(C4Sms9IFJJdvSY(2JRV-v%+V%+<5D-XS2`Df%-OG^q6U!y1f;`~b=!`OJyI!G)G zN@y(N$HG&-!EBZo51d8rCQ@ibM~F=C`t=(CL**FC87$Ft{NBsAdqlvvl8)1RwSh~c z>v7!LJQO)NR@S(*?7oNl54~BzD_MOlNk9OysVOeL@)_6KPfOQ9WP7!w?_^h|ToPC` z4k86bm0ne1a4t)^#Ja5P%kzT3(8MZwlIyrIdMl2*B5;Z#*Jv2#t_N?S@yO?uy@(4y zOBN7cV?Uf_;MI0!x-JAWTczNT-P5iIBsw^u~)pxjV5&E^gNv1$D^ye)0izx5%kSv#-SvKm_QfcU!lX$M1Z ze}OYFTnt8JJQ6)Dajir#4k^TPWzaZCxGqb*R6r=xDj6)Gz6T`NHswObg5k*;eji-J z<@D;DI|wk?#MoFj!^XM{iTEUU)Q?lYat46u?a#3Cz`OH#>8h$_1BkEWp;HVWJdQUu zp>Pt>L1fdwQ5bwTDa7?#swURl9#7Rnk5|o9Q2u(@HP|jdQ2kJ`K zXl#P#UxwY)eX>Y3WdPAAb1}*I$=^tQ^d;GWA&Hwr9{{0uj?$oj1`JtD2}$UOuUq>F z*LUoKC-=aP$12&Ki&6%VGBw?Gp0Q)!km>4Y`sdD~UB5+pxdK3RK&U~1GSV$YERr^< zppZGoqdTE>8$7iK;_-Rv#li~RbTZR%2Iuc{(XH}gx+QaraC@i?^y!uu zQ^s|WBoffpmOFOtGEgXF0I7i7)CAK%b&}~ihtt!C)7^`Ad9Vy8iSFep0HSvlF&2~w zmBqHUR%lMZwzk~Sl(-pPv*=|2nJ2mF37qaeobEo{fkB*}UMxJEU;Zo!2(z5=3S#kk ztd=d%oWN>IK+BfkuhHCO0I8Cko?g84I2PazT)`a}l%!FfFia3)Yvb50_XX#&9^QI$ z|M_Jk1Bj84Myi*I85tR205LMs$^c?yq>%x{$Vejth>?*-1`s17js6FVJEV!je-Bmw O0000Px#1am@3R0s$N2z&@+hyVZ}07*naRCt{1y?KBgM|tl3tL}5oEEZ!H6>r}r_Kkr*r-7S<-il^miF%mri;fkZ( ziYJW(N4o(}%aceZJ_?PSj&>`aRPr=Ho)#_jAHw+ipmopDZpo8M#M36$(?aVJ7&;F` z9mGOdeBfxe=t(0_Gssh2)EErCRD%OR4Z+mck8YcuMDjF1p6YV&oglVDa9o-<@zJB# zo+p_+4Ung@H134xD-bM&${A^Xv<{}edGy-#B$B5A@>G_6uhL<73WzxnoRpT0{Sibv zk50RuMDjF1o~p9*El@iEVlD(rbYA6jAk=X+0%L!A)SCBXk*5LjRFtW85PU_)!Y0Q++m2({VKl!>%U?Eg4NXzTjz{DqySW}-Y^7K-Zr-~>E zJNls~HkHCtpmJ6Uh$4v|hv<W$nQM5S|Lb zDRDx<$nQYoXNRSUPeyr~L5{F&9#U)@QEVHA?V~W+0uUhL3PJ!%rv(V1SkezC4#Ek8 zf)nP#!d_8${6g8*1HFwnQH9#eyW79D7UbqQ(GT-)gX;O+x8uK=RE~B7{{JRpb;W}_ zBx`p|HVr8@A5?4|hHWFTYg}jm2;$IeDvbx|@<8eQfVe!3_t%sL%v`~VgRpW?aOOh6 zIg0{T4SI}%T_3Q(0R+ps|6!GLpd~xPK?cS^Pm1A%}b(4i1kU9GfcZaz%CkD(zc~R1Ho)>{PVf9jSe^z*m$L0Z#CPtk zbHlm@w{L7Q6$M!Uc!6Q%Wq?5zBspMom@bK5Jn$=Sf58>mA5pzbuf3YCL>nM_I8Mxk z`9JU6-1^R2;rM64bN^)e=Rbn-w29S$+`X~R_wS$L`uiKK-6^w5Z%iT)I}Ju$AlL=M zQ!YUJ9?B~3Chd>^!;1Gizoutq;DC5>;{deo1x8``GMIm7c15sH9=QS5TmutZ|JwlM zNy8w~W1CT%wo~@Qgp&z^gv8gMYnwgdK+@N(hul zhMCeGTm~@dv;qlZWN9SL&#*^!w?xsg)15QQA20f1795bB9Gr%d!z@P~AY3|s2l^7fWgNi8K4v}Nv6026gI%h7(_|VT>NPMhl{zL zbWdK|S>nNoAQo!BWawO2cso>L$31Gmh99Tk2oyx4aL50G%fB?e_8cKOswP(Bmb<9m zai3O1ptWuHVLxXpQe1Q6E}r}Q_wwhT-OPp^Q>0+9O(`QOSn|w~qX=iWZpiRA-D zhd_Dt;0=UT>FI&~PP!=-dwo_r5d%|1JH zL0g~{)pdb_;!R7x?dgRc5FOkTXEJUhLa00mSiDa`vJJbrV*fCBKVzkpZ#c>3o% z%yM)95=q9td>zfT8xVm&p)ZJ>oFrPmiSV?Nk&tP~J!=p0fzPaG?WPH25X7bwiTRWQ z!3Bg>o?{kUO2A->%RrMmjPmD;5}??5GUC@3-Ro&)U&(J^X25VIT&c~u;a7uNX)%Wd zjsVzk6KuU6PJH$3oqHDLr~qW-!~e>}H*QSrJE4h00j&ofnl*rI-ZsWZKKBSe`PBi3 zG4fzY!9rmjKU+9T?rL@st}+U4?ben}@aNm$QHter_j*oR^|$44jr0dgpn4HJ=N_1n zutBB3NS4$9cl;hKdklIOmmcnD$PxEJ8fzbC^xv*SPEH|%6c_*qLF3lDW_%7Q6`%X^ zdS3p!Kj-E<_a*r$0Bk7+OSX?|3(AT>Q)XJVGrL?9OG&O+P_!Jql7BGj zNQkIF_#8Oz6u5{yiwI!Lmtko2k!w?jazp_#e#0G1{p=phUDU9LLLg&>lv8zvu6Psj z&`8(EzwU<3T>0BS=DxKDI#BFR0pN^aWy;F-YoFyWcTBEaS((|TKq@XAe6ZjoM|oa2 zcm|wu9$ZYGMFQZyx9Z1&pG0!xdQ2*YKJ+D`W-~FVBv}@bF;JRYcQO8nFLr$Bz56D3 z$Gd*c`#yLV;}b1x0F+A#fcAAWyEvQRgz9!GK`XD^c+w`buwI$TMR}QQa{9pI1&u#~ ztdX43VXNRcIPoHQenor0c0Z1;gH4}0@@*`UBj%)!Uv~?w?RyCV4G1%KrIZGWh|L5u zqBZ`XH_-p)*ASk%s`R+u|G@@6{)u}To`{mssZ_dA{-Sx1wA_|{G095@ZsE0af52d6 zl)Y*R)u6>Qd)IMR&m+`=1_UrgFF%-iC4YD5{j6)A)$XwEf#5T(lKr&Zy0GU^!EZQ% z04X!!#6nnp5&YU}xVN5Vk;nc9j=dWCo*WUik04dBHar2**=1 z!50en#ncP<{=_TU)^Zl+CC<6$RAnG>%WaTEnv?sgQw2ZFH*q-2(($C?AS}KZF8n1t zFqwj1O~TqYz=gNb-Yz}-azp?U?LWlCJ&$VEh!sN$flv~u@qrQo5i5*{kuttv8?`Td zm4UavDRaEBu?GL+&wj!^_w9us==i?a9Y}Ob0M71NPhIr#p`{<=>iO5FWBF~ipG;oH zYj%B`DbcS1oEve{eKBLPhIavKVbLJR^anpmWx5W(=!XRt!TEQ>y2p?wcU>X-{{S}6olK}0}=9@QH9m#@%#=#k`DyLOK7=GT9Z zd+*s*aJG)U;kI&oWjEhD?hmj6yxhQYvn;DFYS;B6p{deK%j)w z{bFvj%8YIWv<{50{*nRGN+v{&eGIaj`D~QO@Nl$(wXIb=&^(R0hd6shgD)KO zw-CZr^KP<$K`AKgyti!sEI%5(EX&K4+K~Z=l%Sw4d&=vnQMy|4KHC$DrK4L_7N!p#h?gK1VW&c298qtZY$7v04iR@7zUET zu+E~|7`;7Bo)>OOK#*DdCPUG9(NN{17$L z89>XyKU=04l9GGdV}#zyL2BJ-N(8K2gII;HnBi4 zKbT}mZGxU^Y&Ln=p*XLTI%%E=6c_Y8l=>R(@NMFE6tl+zQ)lygTR%;5u@$LVRYn*J z5{JyKmq}|gv#?ynZ2l5_0__p({uxgDq!;YXF z)={jf2iDVyWIRfxN3SBGkV5HEDiv=)9}P~e4sm>Kl%CL8vN6lR$fw)onRaBiQ8~a> zoBo}avIY&@(W-9sE>mCR_qWsb5`jd)7279{DLMW@P_1;I*&dNnMar)_EGI1&OJKn{ z&;v9cg@Z?a8OmV=$i&)BNC8qPA^|e~{ZTx$8v!8^Cx#=etPRr>M4c%#Zk@7yN{(Zh zNq(n1W)=Hw1WtTZ1G@w+1hew?kCb;L7 zduNw15}*~F&sBW4tgJjZ4i=oO&8!0-gx0p%Yj+27SOGHm*w&amh$jFQkdf>HuZ|I7|tRbjcYr#C4;!_?kIN}o& z0Y{aTNu6=`NSoJsD&NCY(~wg3u|QJ@3_2?hPJ_8ifJr!TWIrr=co}5l4kD$9l%6M- zO3#G^Lb0+k%rVu;)EcpslLDp2&a?J$ottTyU`6H@xZr513h&+aS80I|5SGo&xNM=k z#R)Kqfa9`8VpWOM7mS1 zWE^gVr6e9O8m7!<4IeNdHtn>{xMuit%B2OW+hrV`D1L{)@Riw7<(4TBRp@z^ z*4Uvx0(E5Gp>}wk^x+92%l{ap!KsxIs+JN9RI!X3a|-4B)`U&k0K?u@Ie;NZ(x2P>M!iD81(Pk(eHXG({0@NO zD?=5W&&iw)Fl?!ut8WA&?=5KO?8#vRNOSKHfl{0rjx#Te5~a(4!&bmD6HBxyH~ahi z3QCUGZV1_pD|plB&FS^ZEt)J~2v=ONC<_=F5EL+p?R(huDwU*sxG~6eeZy4xto z?UXA%ZOXf3i=5(j0SuERYWmAo6W@y8E`RvsumMC&)>##fGbc2xVS&Q}Mq+9eDK}86 z{J`{>rr>xb<`rW#&QM!;sklR5sIWrruIVy~QLZA%fyKl-0EWvTL6u}&UBTx!z0uj< zI**a)(Kd=dOTh4zxoz|BknKxT7AygE42-`Hp9w2jE~2Lcl-tel~Ns{6+OBj|(8TPcp!8O(Pc=FnKRbU7s(TB{?hr8U3ICNb9Z# zEdc0HIALB&?(Dg8N4Yb=z@zAGj-5Lm+5H7@uoo1Z%Le|r|6_E-9y#Ecs9U!L7%mVp zd3IXpbzt%2rIaBz?|GiHztbcDxe?SbPYVAc*LMZwN`a_=I0J_NoMgy-mSxrfGWqo% zQNQlyOkSdAt`A}t`V=}-#{oy?7#`*CwA{y1J_e}=&;+SXp^# zrEL3*@+C#n0EQA;N2;~>aZFwB-4Ff^N(yq~wy*gB`IkC$$riH;jH1&y<>3-&jKJjA z^ZU$#%ql=yn|Ctyfq#ipmfzu3T07B=!gs(Fvr+E0aiW?j4uH=GALWn3Yl=bO^)Gzj zG4T$}s~mWocvvNwG?eh@@G2f3J;~1^nQkA`Op-RVb717kihwg+U=*;4DGyJDgCF2< zu*mEIq!n@K?H@ta8yIk4z~O?$60d`v5m%wDtt()4S)MjfZ{rn9L3L4;h<~Ymm`CTn zlt1YE1|dt6IY$e|ek!nFo;7D&w~U)Kb0EHP&oo^t0CzCU<)sx=y;0;u&=OrVdWI zdzW|3qOy^%+_4;1bIo;=u7}w>yeD3ZBF<$4=Z25#p6yjofmRSuuT&YW_OnAQV_kFx ztLx9^)~SnlsBxBc5@nfFCREvU!ZgBC7NLiB1Ch45)(=x-$v(gH%YWimm;XlcEL zfCjYghw5{!Ja5H<U4m2>R#Cdi) zjN?@uZ&d>}iWB+7-aq4C5Bz@0D4j5f8@KBtVdM~rw=Uq87yk~IF8x(!*EKj!ub@q& z3>4ms87O|6a#v;Tv^)qW++TdmE@j3($jE=(MC;KfQlA5N-Xl%79l9&?Q^;$>Vy>~IW5@C7mt58o6kKxE$C#_N|E(H%t)3LpaSTf zqwyhi{;PiR|Iv&p`QPCaxdWmNR`Dm!&b8e#hv-u#ku)PSkkn_Zs~K;+mY zhdyqG*R--__1tyVV<`edC+5-NteZ34;&j8jd?8M|dQqlu%86$l#}%1lomAPu*?sHq zj%>+-cm^a6SgJkx%_{NnMwBOq};p( zd2rwXg4%x=e4EN28bLUXXHyiP6uF|@^sym3m&IVHvoXn0g#@=GXPLhH?yCo zs;#Wf?wMlh>jZ#Hq2#_ZcclXU2U!p>KGa?9_h3T938Wq{!`qYS&a?2&*6 z=${8FexOPT{&Vw{eDcvQUk=@RIA)TW0HaNQM`o3WU6hj!=EBfdy8C?|nHE5XzkNIM z(3ryrKC{X%{#CrTlmIHH_+{X808pyTPMho!;WCN7K%RrK02?q=|i{yYJpl6PrL{z$S z8?7p*e)|@NTZ1JX;Qm%X9)kL6h{n4EhB;VKTG?re(}h5>8aa7q`EP0?T>&IIIL_z| z_j=eN4n-zNB(*+NKC@FXclvInW7DlsLfdoLQj@Tt0f&0h+lr4W-8=6k$#*KMc%=#IAavihO?=2iJl9g4*Y z(~;=_Z24r~oN`&jYTksZab5FyoV)SMT)zG@JTUeQP*OkKqZEX_+SF08X(cUYFrNZe z1tD&}B4MSjMxeq(Nv!!UIZL?aeBY{s+G zr0Ft7$fQ+=Y0`Ai1NE)lUF%pn2FSr{R|8O4I+(pnVf4)Hxh`e8ihd--v~6J>dfjiA zSYdo^hE*T`+IT6;9{nCyt^YXd##dR2FZEmCd*?#WfR*or9fQKH>j1?UcS9-k=+?Yt z$x9z(B)IImU*%H|{{e+F?nZKD4XED_t-Tf~;);d-gqv3WbaK8f(g@h`!7eU%DxCx5 z+rNS^p#S-2T6cygi5w|#3E+frzp^Mer26^b@EcgN{(HP_<9iv4=A@vIN}Dph^Pz7( z1hqUMY>;Gt;sHzBJPRl}Cc&R4DloWAw=d3n&oAD`>wfxKA{BanbA~}Pn}o*0(AWSf zq8KQuAdNrm`WG2ssN!^ede4Y-1d#E2w$Rvlki~C*2~!Vlp4N#Ds~m2;+Q(ly1-)jV zLf=`(qaMCGbtxxr`U-!)=S{Q-wSt%n6xN_`0rbvGU+$*xvqn+8kTLM&IdK;d(glZ; z?whaM8|QuJv6u7uAO0WIC|!aCXzhT>`$1076%e{Lv+MyBUpkoHvcrz{8v5S7RF9d@ z+$)|%W8ek#w}`Y*h7`~PG->P09?AR~lQKnS%#y@}Az z3Pm7s*+kmP;D(*X9k7)7EWPuzk0b#J*KWCzd)A!;@taD!0*M;eAZZ;;Gp7rLnV4Do zz9f#3LI40D07*naRN3|A?hGK`xt9|^^JYeVc%QdinFb^xoU%4DEpX(AQM;0v0CGv4 z)erL{e2fGT6q{DQbSaxSaY;!%b9~6po5b6k z#R))=aMhasOY5-!9wK>?w_}hH!PGiv>?l$ESpY(znFSp9cGs7>EkMQ}+)nSRr3_wn zHiy2uy6pk8dS?Trz)>hw)Dq{yz94PI8TwQOWnIVv$1LOH!@mJ4Kqy5ZlO{}`8P)@O9Y8f90-VM8fdx56apB;e& zXl#b5$FquUx5bynmo5QO+0rmnAZTYwz=(K?R*;A%XSvIjjQs|IV01WBm$^8C4bIk_^?+~)@ zSY)@}K~l$F@sDf&kZl(%haq4!`V-CFf~2(@2U3vCPItAB?_4t<_S!SCkf~-3p(28yN?4mifJgvghh}Tb z8a~D-WDyrUCEzGc+o1831)*NM6}P_?3Ep?#d*FOv6!>Kvb^{WHo+p`H19Hj%2A!u> zQQGtSl+yDdt%93;fs_KId0?DHuXz>#BmcEF$yeS-Nm0m9(d|=5jMWI7p1dNg`rxZAGvd4Avi;iQ=tay_1>kqtw z?Z+;M>z_=!teXO7gVNa5lGT<}6d?P#$=trOHZeXX=uN{G;0h15u6~Qy{FN#27eyb@T zzOCSb`=t~hm4*EPjNbOR)jntONP!}y*+q*_Y_S-q7l**b^QhER(vtWDowNFs!aQoy)u;yUErnpcHoC1A;!T4rWV#4aZpAxW;&!eH+@Qc5Ko%g~a_d}*xX}{cED#q{Mnn6I zcuXu&-lDw=>XucH8!e-N$?+;vQ#Jj5;6NclNf3v%xeZ1tJ?v~QWck1$mJJ-t{2n6@ z>^ns(w`j%6uJZ#4GH4%H!lV^wBTXxmSqPcAb=fC(8ltRylI84iDD3JgU1Vyf?F%NL z^yX8wUWly}KYi@E>>XRk(t#m38(2pQik;~96t65eR^g2(g30yJcP5CcRc@h6*`Y5_ zS;utp1hDZZ@W6lQ-#=FVDe1NV8GmROvMKda7Dd|0O2jwdJX<8-iR-(dNs}>1e0Q0g zi1f#{1&{?81(TCChDZCDn5@y5sv-o0f&K(T7%0L(5(JW#sPLKnm-EAs^Lg=!YxvoY z^SI*VyLrzA-{bhfee4)p%$}+FoWE=XKi+ad%m8L+w_9L9AQegkNuElOp+E{t@qL>I z1ZKmI+rWq`CUu+(V(J%3rAM<*+`o|&-0<)v{N9Dv!)d@~U=j_I0N4fe0m}=HR|FE( zf{DkV{~07I+9^Qny1qP7gCD;~ziCnc^LM5&?_uY@dDI&f!T|lo`9Km1MSvm{iV#I06j31fldW&y;fWKGLhz%_ z&qj%W?{2u5A8h_Le)p`KdDr>ZGdwki-@fsEJbvI<{bqUsZEDdiFci{SKxczRi6U@V zpeSSwCk+lTJWPU}E|H+7l^>ZX-%r*g2gXT35}^H&v(RkfN*PF^F__#6y(iF-`BcUnHn2kU{EYx)`NUy+fIPg5 zJa=p5&w-@_Ch$$FK|yBE@mLMlPZ6iFx)p;Fq!QVK`Xi3W*|A0eDO-7Z^tI?Q#v4G#?a!3^IW6 zvWe+vmr)Em_<&*ODXVU#tKAFW-qp~4flL`>_n`%BK5#52FWRYp#wloD#9-SzqP`J0 z1H8jRWguxCfO;>~7InuGWqAQ9gD~M~P%3Q!GPz;DrJo}1>?|{w(JdwP6)|i>9GZR2 zU0Gy)q)*zJRxW7tHr1%GVdr8HP!WnC0fH3@vVcKx-M(|zwCV#0H0nix?;lSj=IH{1F!zE+`T} z6q#6_3lv%aiI2H%=SmF_fD_Tfyymsd0U9I`unkyIaNWy5Qs1GMiG*{?nZu6zm?QB+ z6h!eCi-So|V^S#{=2ekoYRgazjF=%Tg^$mc4V8|&AjurpM@Ryp3a_U=SdJ?V4jDaFZ7z9ET<3WYGtODA+LP0I4>5CsI zK}JShC=->j;$xM+z8$P`2r1 z^{asF2o_do<)gAUwG1YTZfk%r&!(q!Ht$=OtN|r0IBaB)^{rvE5FJseU4e;Fv&NHEF9Lzbb{++Py(2&|DmK{ z|G@$6b3g_VDJYb~CJ-t`5GZ9DLMpA@CZ}LnH=EWCO__q6 zW1fQ028QaEhkbJkrpX)6J!W};kM_b!d8S@;SR&;B*)@tnP+2$!4h=)>XuAxd z+vlG+%nbFW*%>BD$`f{Q0pl=-RX#e|gNg#eKw8X^1&SWIiYEuL%rB)_5Y)Bu#SIFT z&`$^=^#F|3i~x|v8#j3+Gvw|>U>+<*j=7&XvOqCRl7a?AI`U<}qDalKr2lOuF=?x> z+lsJ8vS8PtMS9dQwBEY81idcHz7N<;cM#}_w{BQOHK26}D)ZxX7tCP_Cea}66LF+i zN}crj?lBZF|HY?SzyORnWtc))piq907*N@xS;>$0bx4uZo?#Zj*m!T^h#Tj-5-Yzy zPn%v9p%4M|ge{&oZwmtB94jkS83$b`NuVS`<`*ZrixSHma~&^p%}GJ6wo{sBurGuOIJx_%)2J!Q^# zQQk!Sjg+~7Dj&!#XOP`v^sZP$?b+fW&5&w7l60 zsMo7h0+|fuCM;qN^M=UOIaiuJKx!vEko?xM_w&m`C+aiC00Cn%2l`^z<`bZ#NIn5* z+GH5RWt7y%Fl{%!NV#Kf>S~tAnpifIXy(Yq4V$EClKeDo^?xUmgqdrlG9wq0jT#I3 zoqB_4Gt2&LghYeGm|m0UXG+X*-Sc?UE$xp~V;jxK5}CM@Hzjo2=Mp!jSlXIci(Yvq zvL2CmfH8F&=FmV8iHVgA@y2(3V|Hc1V%lpt>2@dh{0`T|Qi^(`LM0w$3S)){9FXX| z*yj*RFAoV6u_FQ@Tsm(vC-e@nb#j5ei_0KU{34J*K!DUM$ps|u+r@RveSnybd1V}P z+fjE-t!!Mx*F=A%*9MHqOVgRYZX-&{WXRRjo~-xe6?zc;f(Pq!OXkVm8s;8yq zl@)IugmA9oOIdLrKtNx|W;_QnPeR4F1}2qK6RWXrg2h*!iE7EjG}4z`#AcP_Ul?{t z>S3{h>$uy$TUhl>W_uH>)d;DG*o0CV5Xl?}dhR31Lm~oFaG3871`vi3|9tLsgea6u z=NvL-mB-w&%Tv=P`;b(|V5k=1R zQow+vVYb!nnp$=8`}#Kf`pahe>_|J4%HE{ZBUp2V)`9B6G6<9dL^dV!U$7EUt;8c) zA|1)H{0|#6sgEJZfg%S2C+>TeBhyJ)-z92R2o+R>jDbJ`h-8wG*rXB)gfXkEO=!TJ z+JAtLp7(ts+4TA!fjwzh02Kd3U()#j?>U9PJAFy;E#6C`3 zKF~9nS7?Er^DtnrfnnWWnIL`77S1us(#>H@`6&m60Y@XI{DrX(6P7bbsfjh`tYwI5 zh^U6x%5FR7#>6tdNaCnFK8SMmCpn_knUFQF66SEtE4`C!#S??Z*GT*h2$WvRj``A5 za*+%$OkBnrykgmUrY^XSkKOk=f}pB*vP>)eaIH)hv?ddB0oD(&qx0C3RFIz=A0ZDTVYR-_a4;UsK5t>1k z#miQzo;eIWnOG{u5T^uxxYR!JBGB`oI1vWPtwk~rqp9V{`ojMJU5nBt3-nH}}8 zNt{+vBnuA{a45Z$L=7Z4qFgcghbA(35dC zIPCj_Z8?Cxv)hA8WdJeh)CCK_QZxUSf6$K-iOpJ`HFW+CV5XuToIBL%ewwAv21lyU=C~8wgo|bOH{g z6oG8S*Hc$sv0zUzKx_?DPH1-<=(jYwL&fb_L^bsb7({3qXoU_~P_VZG$3`*0fj(y) zSxNIV(tGUOM2oA7=VYAp#97Y(BKAEDXq0`ovdy!UVZh^uBp|VWtYdNk$RJ)`qMdPp zvOr;(Pd=bv=i`Yha zb~v}Qd5Jx=4RhJI5l0euxF8#I%Z) z#wruW56PHWj!Bhs*ma)9M3SNR740^QU2>oimf5A!^Gc|NE#CROA8^`|?Rr= zc$S+Gm%E^F@`PQ_Weal(drR_^6Uw|vMhw#APN&nCo$>%vQH^WYUc&nQCz5^hh|k1| zS;1nHXDr#urKjA-3r@M8bB}wRAXF&>TH!#o#X!#lCoR~?g)7$bj*Gv|fr`{efG(lvLjPIv4J4S*SAeB>oO)% zYGx^jTIiWz{49ckeHA#}GOq^DFaDvibOeyFze;7vT;%>keipF-5r^LAL*g)D5L5>y z7Jf#-QD|Z3+3X;*Wr0ZZjH#8xr7p{yo1_gwC|-HSYF>HfYBmlX!}lI~K6h_Fovp)5 zh*ZTgt&Hg<=&ROw&WcBQ{>n96a>|1oGw(op&bV3L(2mFJ0~hrl;!iL6I&Z)D+kESR zm+_g~-oUPrB_-yS>317E(`OF=8WWhcY5+^;4s+TuJN@l1I;6`Y_C5kVn&s|O3J~u_aLy?LnUTb@+zIU+Nwpn`12QD3js7$$P4>#i#J|y1Ft*pC;ZVj-p?%?F2oNIzjjI=(_K2F}F?*yx>e90wE>>QjxYya7)@OnVXTP#|?s;|cVbuTx9nPO66APek)ne?m zR;f=>G?HcKnO|-DBqYahrDHQI^T?*ig8)dLJVT`BQ$WfrMnf|G1{QM^v&f9Yc6lC9 zBodbeLh;d8f0_k-!~EY{ulAT%ko8I2d|Pa0At$Oa68j&zg94$r;#nOqi2YQd`5i8h z?0cF-Yi0**n)a2{H@6%xJdC1%MbGy%G%pJBs$tq0|gGjWQl(~Dw z$F{Gox!MAfTbVK-A$#nEB}g{|iUcH%|Kf&p5c$vi(gdG*sPQ;cekZ~LHv*N<~La%NtXJfBy(z0Tyfsoe7k&` z{n)qLS3dL0?9)xZn(v?}JG3{etTGQ4TtFw%F@pfiJ?}V1e!d>5M8Y0PTm&d3W45s3 zrDj$NjN(Z{$j?cT<_G4E;X3BJr-cwmRY9pp?`};*swi%OQm9Y?QQ8DEpHXIhnbY~g zPRpjt9GMlyshqlGYdq6!59zw>0o|^{l8xca3f?zgdOOu1>Wo3`&qcee;P#{a``p`i z5#uENYcWLGXx5U;3mTf2?f`QBaU8nkaRS#5am_5(yz-b?xd*FaQy>{aG@X~Qhlx92 zF+PR)@kSA}mV=N80Z~)|p}~-hR8{nCN+iCDKp_#tZ#hv)kDJHG78PA0gfa1yb#a`~ zm)GtByYWuUE6WcdfSp5&38c(T61H>BeNMTlFJ%kWoQ%gr6xB+^J6`_t@{uOHeeP_z zsaJH9F=g)YO8d-W3-ANOgvY(s(@?*31&{@ooW#~orpj%7p^wb0dJZHuyVxUFDU+mq zmAz8JzH|G)B1lK9;$tSA5~oGHsIl3sAu91`N1zb#+c`uS({Dv#-qaza($9#fP}dJ- zQdda@K?D_r2vs^zWSZV0^NdYwx@a{WM}89EL^gXFv=ve9wg# zY1R)VlY;`q8(*-RW%EX|%I@Da`Jj{cx7w^y#I8jEEMkztVcxh>We|>iji;f0=?Wl= zEqs^$Awv+X!;dE}++99pPfCIQf9 z{T29uk-2dTXf;MaYV)%aM!fSC9`?xX7>jLQWlvMiu)bp!#m#|>hI#G0W3Td@q*%HF zNH|bq@PgwRUA;Lmvr0#^9FQP9z_87(9QDUP-8)%GqWoHcgas-?uVjD}hD~~Eqf9my zB3lB&7#N|{KnNA)5nNGGh?YbJ5)nylhE)`_V!#9v%)X(DXUkKN2m#4!agy~`3K8i# zLMT*7x{uO8N^S!216@rSaO2vu`0^dkWzF{EEWHq{89$Z>w;Y>{-VOFIB@i;UE=8;p z`nM;HlBCn)xEK+Z7Pp#{$kt?%^NyF_%JGX1b;cf$euu*bL6M1N#25r+K8Sa}HteAk zobcNP4fRV`00CI|;#G{S-V&Qw`fD2cJ%j;)l8IC9f;60}y2~ijE7zB7t7dWdnvdKTYd+5Grolu#&&N?q%#89Ym|GOb6`*C>5)+f-vYM zR7wv>Zi$&Aa7--2Bq>M|VAwv0Z${p6)@>0e zN6|$_=~Ey$K=RFmORao^1G|~1&trUIDY6-8Wez36Fhf&=BgqS5AO$i3k}!EOs6@pm zcnpj%28s0yyodpzg0zmpsvjzLkM;A9Kf8n}C%&89Q zw~Q2kLzsRwtO7~7Ew;`zn&U*RiKOHofA4$rR+@h0En<+SQ`co4Bkp9PuWlJY1SC%h z7L8`D{KJAq7EAX4x%dQvfnL=3xHVyDnOg=JDnJOCKG&!qYnay@%-Q8)kHDIU{4o#FO$CPy!ne3L)Y!&|wft?W_k1QIQD{G+=Z* zFw7Dv%}j8%V<32MnrL@KGRu}Vev zV{C(a!C@>8Qw9k*Y_l!Fk&;Z+_a)BxRnJ?)3(wxz-k-1~BLC`JpK-0|5dZ)l!bwCy zRFeCA8HKZy$g_V2AR-Tl0mB|V;Y`Sp0f?xEEPeHv?D_h=u~}unp;;sY44=6r6iS(8 z?tX{e?l57lY?0D;$|9L`y1x*L!FfBGGq{(Lk>eOXbS#oeYH|figCyQmpn;;Q0G7Y*EOveEzQnB3zDVqc;P@dbK%o+6T`Cb@ zkP<({0);*7D{N4>%R@4N!2yME7=#>n!m!DLg`1hbXbXo99naqVE0I$RQgDbUVFtq- zrcC=V#vhR>3kj8&VnW0wS!}L}Kr*i2$2*qrl{Kpvi-7_9<`M)I<_3dQf|~BD*nCoP z|LN5-BJo4af`DVcGn%5_7)AhnwI*MB*SF|%O)KAB-<3() zgTqeSH^HJ~7Mffts~2{;0-o__o`bcQX#r&M%T6I2=tYfBBqo+^YH4s}*+VM*>V9G7 zO9}y^0i}t=VUG*|98j3fX$uPFq_g#eP%K!qmAfYu-`ILKS1cRj>>j8z=TILT)c%D5 zL~Moyfds=ULK1{_nMzHyK+y=AJTh6~mYoZ@W&2X1#0OBxqbhx2FLQ!{_%}v+2s{A? z7D!TX2u(XVa0tW585Xhq5hJ=Rk}bySyA#vu6MygnRxLk}_Hn1|0op+~bzPwN(mr5x zYGOe;YUmzk`O9F@g$0c)muUecsD&(kRWf}+^GDh?GdJ$@@UJaIDru>Lpzmh?|>_QE|pbFjt9J}?4i8S3YrJqvjFfO&iwu+2#!sfsEC;T)=>ib8@EiSp~N zh|@S}?PwH&BgYyRFp?o%p?#Xs`X2P6#DMp|{${Sc;L)sU)v5o{@Z|gM>{$J7=b7u# zDf1K^UjgTS%+tWmL@1?vKd-Iqx&BcexawBnDYECJ=G$k!}&8mDF@S0=URktQ2?NI3}_thiKx3@TNu+rq8F1eL? zVL;XSj)Zdl*(Dmo%5fZHwT;(;1yV7G8jFJg76)_b6Z+F{`o+~T>&9=Dx8L4wUTB^9 zP>=n=9{c6j<|Wn1S8}ZvT&wg0J3>k(8V6{#CJ<8c=1cG8J+HnkT}Ng5%8lEL7wo)< zVsK#XV}nCE$8z(^HusqJ_RPO)qsiqmZGebMzzJ`=02wQ=G$xgDKw$D5u%y5e7+@rMI)9=*#8hhpf#hAUx`V%Y{m=3@k|Jf%z0P*4lHW_SZ$e1+r$F>1*%()|3^Za88a&s#?*?urdA-b`L1b|GqoHO zD>1cZVqO*INpHP7cOS#Y?|2z4nZ8Y+8Bf+p^c&x$lBolXwgdwq2nnbV5Cj!#*?Hbn zDtjAAT296cbJN-SX*?~n%9Ua?8fHA2AP|ZVzv*Uv^Z5_iRq`PPXQ4r1=*u-^E8R`#yhv>nj+oYoDYloX>Z) zQzB(1PK_2AjmgHdb?}s%uTCkeoVY9nMzY>2_C4&yiV>1StwYpho%wU7_|#i(;*ztr zW=95#obn={!6>#pdv2Rhc=GK$th&B3U)ny79X|5|GX@9DkU;RXexcKyi)X`hUpt+~vuxqkfk;V) zT0^u{i*rue!)M?ABbF@~x2tC3-8kqIG3r|`<)2<`?MO~jCBAxQIe*P=E3ZJiHA1{!SC~9z^xsOOSc*~3L=bP{OF3SeT z^L|9G51qKrL667|?<%Jro_+1jWrJ=vbL?|IG~;VyWJV^Ik(GaWF>Bxaoy>$`5(;f< zNu|f{MKZIlkf?O>Fta`@HML}HUIY}Z^!1uimYId8PP;s;H2L&krO99Z+Any?s`Y$! z^`-0{8=O)931w@A{=Hc<%I^?lO)=XRQck&+aXHCwG|I~5Lwxv+Kj++)d(zXoeVVu4 zicK3M#yK}qW-7Vow7Z~_^;?jx)v~ue{V=+m*^(JE2*9zgKZn{e^D@J|%3+f%iv$*n z*u%dmYoz;mMzow!t->K)ZyxzOp>OluEt9l9)_F^J^SLX(&1=rQKmN4z%q7ntD#I)` zi{wYR@}ppZlti+@{^kM3)e!G|`CVN9-fKB`#h&i_pe(;d*0l1ONkz-!&s#2fh&R6QA?Efq^1v{=b!uAqz#-7=VZWxw7N36sc`(@5uoHmT&b$Kl_QCpv z`ZEZFiIP0!%gji)j))qc6k^hJ+aNhO&ICVAFrkMXJt*K_Gv+w@{d z0|Lm$%fhm_Nh|cMxsf6UDFTR{woNRztSGI3dH_FM3C$3y3O@Z!IHUcGsXLKb1qi?$ z&;A1A4{Xa0`HFPXu;K#483GOhdySSg%vkQ>WTQ4~eZFYHeoi}i3um9aofn+3jRkY#2QkWkF&p3j?RU77dalW2>KCzz z5!=Ucr3g>}KRyw5&(YvmSciYR5tg+7I8G-r>i{`;=QdV9|BGILRIEjeMZierNGy;D z&+K~X47*U%1B4eG_`%U7NU&b$AO$>eXg=%rE#NzE-=~w#ZI@-lY&JqS2qArq(Ey25E~p1EP~a`^$Rts z3a(P{zaA-QQ1>!xK8TS87oEV;*PO}z>(`}z2q8kLBrW0>xY;x5A~Wn;;IJ#p9|5xO z!-^%gC^~Y!+d1X{Ia|M-#2R24X*O%TFbEVUFF44_3x~Mkj7K5ReKFChFy5*%(X24u ztkRSLb9x&L^fs8&+hlHEJ$-$Ut?bfCD=XbDUKT=LnN8Zvn7ik+L12rt>fwpo%uxmq zt54PLez^5G{h%7a+$JoT^6Wf)nRS2wobi9I;MN<~BO@7)VyVo?mav?1f%Resj{~3f zNBTAtdu}9mVPg@lgKpxTI_7phkoR64DFH-bU8{}|FsIUDPOTNQP0TnZZY!#-=&rr* z1A|@G4kY$ZECPol1&4h%FEX!i>bQAOzV^z_i-DxZE65vHX)TE2f|qR7%iCvB4hul~ zR?KI`yDs91PyPa_!dT%AKs1{K$asXyVvqRYAc^&gAkuYOMt{@!q1dEyF0^^jDmV1o z@i1;#zVG(fg}C5x!D8adi5sw#fual;c^yxrEC2yG^@EqP>ziw6?Htl5SAhnLiorsVH>*@S zBBkR3{i;Eqsg;5zFdxQ=J3Rpn*V0Rc^Xd z_9!x~iojtjHJ*GQBfF*&@U6=Da~wpn9i)rH0?e^l0G})JbaaT5KFU+%mF4p+n#y2D%tSN47+vOZ5{3t z#amfk5)b_OnJ_5%4FzdcP^Xg_bQ6!zPPug_hl1l{g*Fg;v*fZM-?stH2al!s=yH-z zZ=5(v@QRK47|;6CF157195x04Sn{${IOa{~v-_*}W}S3G%@CHu?qd>&pU$&PE$x2< z87o8z2$1Rer6PX>{C741ep`TYq9~IhUnG+!K&b-rN@(9h0fAM|{5JdRyk%_CDQoyl zE0gCNdNuuM?% zumS|&%zu742X1$Fpp z*QuY;p($0AUuH`A@@#M@K{9mg1BwqAc=C!sVd6eBi8wzfD7RUo2uLRMnNwu*l>#|5 zhlwAbL!k5ltIys}?fh+;Rh59V-&Am*naN=XNM&9xXMOQC-2dvYWE}R$fI|lQy-_wW z45Og$pmv!eNS>sH^d@U=bhbZYz~Xhk*b$lQxVkQ+IFkv5ss#h7k?m5t^pnB`{zichx;?Wcw zl|Fds7dRYp*Z~5t^#8SYwlQ{Gxp%#9cE~y;CLu~l2vNW!AxiD$6;jHJkSi4> zh%^KXNKp!+{ZMF;ij*(3DrzgyNQk(mr3w(K4S@z5C|-NUM9!bIx3QXU=c`&vVYqncusT3pZcSq3=C~ z2{Ppf!vGT`pr}v_tdG|&#JNS)qlhr7Gxl#c5>5{= zxPCu_8+OM#?WeEB12%1;Tecv80IdJ!CQd&2Dl_|zr88M=?5tKTepg43fRW2ZNPS>c zB>Mvd`LI1COk|isOrGBG7mBMm*Bm1?PdHYl8oIrp77i$KGg%&J>`$QT78aj+;3&&q z&GjqF!LR+Uc0G;TB>s=)l*i=iVOZzHzu!nuk2v>Z|3htc@qkAoe=>+ZU<7x##cOHj`PAAqT~Qm5fBdq zzOH4ek=AXZgc|}EG&;OWK~Z6r4ZCt`f*Te+RjbP`b&!f6H<;Eyx!{R_Rx(?MI#vJ@ zVi^1RHLTh2600s4jh$@~dSSo>@bMqfO6y!jKio=v$zYZPe>PBfLn<=G&`Of~afDvh zG`z0R%2(G4p+EI^whT12a*z+Lf{1W(kdYg9#PxRaOW1Q}0on9-FmeUmv;_qO;G$1l z!`SxMc>SBdNRo7|Bo+{|{6mCWA&7iLhgaEnimzKpAZE65TbbH1(oQNJAt?!^d|-46 zsnT)+j}M9*99lI*n-d5FCd|V`Kzff^@<*hg92PkJ>#ILBPQ`E?XWJSz(%bDTfaj>AT=^_~LUN{=xaPMFRw2 z=I|-D-|zs<1Eb0FBXX}S`P@jDK4cX`5fT*2@k3NjP>9lUDJ1ePTJJL;jy4xK(kGq; zah6NrC;=sH6CqS5NCL>M-lr-e>bZQzp(M6$Lo=6ZNMExC)5%*&D=UZSXMH0V#m{;K z<K1X@8v zxlBnagCajeRd@A)6c#(sWuhM_<&dhOVbFkR3k{sE3jk)J9JU?-Z+Sa>@mEmGwtig* zTXaAGCU+g>*YDp-I69{G^KGeT){lTTwsuaV0|uN-uXVb_tEk})FoRIfItGtZ4VHg zoG8GNZSbJ-jzE_+B$;ZIK>`#vfAHlSPCrFpyg*b@5d1K>;P9$Rlnr*5ibzNz*&lK+ z$O(sZJSW3OP8=Z12Bw1~?@$n=p8^Ey(+cz6&%hn`cNjh0vn2xvz^NUFc>4WYh$c?u z;7H3_IdV|sRU{9Dcp1-JA@SuWT5T30ys8R@_F+GzS|}(aFgkfp`v}V^Oq31mW-Xr5 zbwL0gXapQV4L)%{{Pt$wa9I#rQh)%AKm9t-erPMv#AHE5T(eg;anH)d4X}+15=Tw~ zc}Q&NHK!2Er66+&uQVv7V7PpuEjLT05_`z^)9WiPg(C8>t-=>x?@WY5Qrgp<^x;c^y$Lu+iEH~*P+#HA@B2~!cAsQB$pCI~2#EW~4dj5X5NOX#{51}RoKKOaKef~C|K2uwgfB;PH zI>NIb*-HD+iNZ^G0+G18ppdFkghb^evhGUQ$$;rNW7TOIcTQ8f6~M@aU!tsG@To!w@jA(lP2Xbb`PUqw zmQ;~24~z)KT)Q&P36f5E$(e>%9YGOoIiKiP8diB!1kr|Q*L`%@h5Bp;FcTD$Y}+BH z7_zAbAO0NNac1ul?3OKQKmgjOo9w##dz}2~bBQwKw=lKJQBaXGND85r1SSJRhgp?E zt^z=^U6g$aA$?V6u_`6!s@(+%zPhiRe71vl`%k@Tw^R;sXj;DbO8Cn7yY1n}e~R8PXoa*o-qeYo0@en($)Sso|ab9Hbg4pcamm_tpX zzCO$c?}0nN3Pyj~(zIm-2*C9I6TJ8b|IE}gdn-fY^7&OHf8UlXFY$(4RT6Yp{*lW= zDyT*&FqFfBE`vARLin`58F-R$bx;IhP$#(UPPpgmRWI|Bv1JDcKs3{4?|qMQ=o^pc zrhwg$NKkA-Z+DD$g;r8U5}(RT0C!odNm)`p+qDlb7%ra!23M$+mchLk=m@bQ6DvoA zTRF%Q@)`PQ-f|bipS}-<*39lAFA-aofLJ@Z?L~Iq^C02zaVI3%?3T_$WZ0#l&}$(?$-=BG?8+&MFU&%zNfjmOl$_6H)~W!B^r?DT zVlF|6C_YD?GsCfowd_841*7I2eE1iCMSZw`?iY56*s=%2+R=x$v+vLT6*GBSy@W>q zA>h$3>2a-#cmc5?R~0pxP0rD2?IUfY=+ohohGjO&p+T{azB;VcuCx2d#q2qJ2~#t} z1g6G&ANexpZS3x|;tORf1`vRmH^$g=?{}Dd;swW>s@$NI&u&F|MR9>srX~WKGg|wo z6lRICYXu$Ex2kgJS28E|`q&7s9$Ux3lNS(0bpmPxL7kiaelr)|{=T_i#3g1c3J_~Y z{_$rV_{#S&jp^JvNKJ#HauMs(Q@-hJmh`8};#LzUG*S@?)4R5Q24MIU!#jf|RmYya zq&=db8n2J9VfV4~IdF1>cDO2r!UP1==&y&|^7(gh{+Is(Ou$O96$uDHWA7*jzVZm; zKYq%&4&u63tGJ+846TA37z&mW1#yDn3$NxQId_FzvhFHdOI+>9uzzfr-;AEifw6N4 ztx}i_jJ}%Tigm}h>O+??{M9W`TaYM5R>jzhqa#&mOfB=M(4c_>hA2Yi3F=$NZ!6@V-#UCTrN<4W;=8MZvq9D5N z3cY+lc*80eEa1MqJ!_jW&^8eVPxZ0$*dTjP4$%tpFbvcTYX_T*477OjV1u`vJI3n% znfTm(^j?C`uB@<1+F1dJwbs!I4&VP1j(_`cOrzmZ5~(1rY2YFZR!uTrdDzt%6v|C9CW{HIesi>9EUp z`#e+trBhhtYtzSeT>H>QK{IazV zS+CdO*584TejIMN1(wNk8{M)VAXO}inEKVrOg{R*G^#JLXwc4~^IY4XYE3|*JkMQ6T!b3-i-Z(;Z@GvwRUO<@Tj29%S!dup1F1rNt zwoBo%OX2O8VcvNaoVRw7PQvoH9w3Wk(TVXGnB!wa(+!xOhUo@T^2yW`CNP-6ei$0W z4D`d`0A^?a1_m(0Lohf1!$X+C!8mL>%MjBcU vo|RY+ke>Cd#Cm}AtY;?pLq=R8UEE-<-Z@pS`eGhsw!_ z!9rm|ef#zeR{XcH0`PPAzb^=WP@5Jy3AB?#cd3&JSm z+c*4g;=%$-ZW-s9o?degonP56hquzJS{k!SO$`nF6u%D^cTtMv<|)z>#xmIL$T{Jy z?yN#uCMLExlIr(5cI{5>@zd#1I;3b4r1fROa-<3iwV)JeX&M>|39Qo^%r9R)Vh<%} zwN?cmj-#rF0>ERuY{hx2r`|q&#@>Cpv#W0c^BWrz%gQJpFTH{Tz~Sspm2fsTTvj4Bp*veBz=W2}L+(dn4rIJQx7@6e7#SJ;>vZw-?F%?W-wKXb7vO zy(7RuJ6~qvcwIk*tBu{K$XKo_HJdUI71TmnhBLD(Wk`A$YtTQix&Au%iP7u%TA=kQ z8C4f~-|^4V*+J%Qv%AZJ;rYw{H+iS>u9$Ty3D}J@Ov#96?Ao{wl;k-ozE5>>Smne zmncSMa_)u$8VpN1R6Mk2#xZC>+PpzdLFG!COLh15C2Vx@a^3Eu}26ZbR#L* z0gFo0g3~{ev5Fr&sRRYEJl(s(WL&aN4o&_2(gTX__fKc&OeW*scyD@k?AVu^tg*;s zGI~y&9L_46eP|WVE&X8-Jo((R3;DFhbCF?nhd;vZ8Y;+TVB^UrRM@DRm;=S*^3Fj_ zBB9S;hoohq8aWFu{4QGXK6$ff8S2K87RU7MD%Xo?;R1-4!#r<>?dOh+N z_xCFUaL&08^j7MO--m2*+xMsNV9T@IBE;}sU`@(-&L3Pi-Gft^OyN#Dfjj^0`fW(^ zWugBoa)X0C=#jt1s4O-xaKuc+FL6ziyt+21v%7{~y$<;`T&go}mz$;@>OQW(qOMK7 z^#eN*_A%w?MA$Fx$ImS~sW3`qD;Ydn-1F@cu6RDHcW8Ha_Ya>Uw`-41ueTtBPo3Ie zNMzEO_;?|A_tyK*^ObsFg=0DER3X)nv+&DSte2@@I6A(r@Cef<#YSW?xvFyZb>W9_ z%>_%rdE{Jvr~{>l7PG6Jhb>&r)F5d0MP<*Y88Rs78;(;_ok;0(Lsjva-a1_UISIu7 z%AkDmv~okpl(~7;9Dh$*kNJ#AlQ{0_3|+YFJ$T%>aqIhz9XQBjagSJ5TN(8S zJ*aWEzZ}r{j#T@8SZ;cp(OkCd!JS}&CLcIH57)LlVUTx`{>CdQE#1j_+1kk#oBY-b zdUWx$3rBkj8YqrPDLoJ>(}YtyxKa5QAZOS{E-57MBKVI1s9Z}v#`=p8mfcRXsSX2C z$~iG}^SZWDYiEhL($aouWkXjGd#Ah}|Gxc_rqMT3RP6YJnU#yavxl7sLsj#jWmp3BosdS_Y3gIOx@!?^a%Sb&7sWgtV2Fj5+MJI(eXVnu^bs7DD@=4Jl z>Go4UpDeuBPkMBi_j6OeJ+7@6ICFDzbeNzJv(Er{-r>DyKH3jHI!kh~Gfa7Ml%HL? z)Lzmt=q*>9c(s?&z6E3M1VOPgM6kDtB8(4VA(LxB(n| z$`NOoZ74>kiTlN&-#v+f{9wORDB9=6Ym>DTm;NGlX}GhJ$u6J`B9t!2pUWwDwR-xK zt(-q|Jxml`qu2Xmc5ZGDcP$-%#T*Q7A!|^N9_G2L_L@b&V+UB?;Us9YUB#t;$)qf* zx_kzvC`9@k+96Gu)%oDzwFH-iOB_<9LeIei(8=gs2jG8!iT~898%2fh)ziBnw^kZK z5H=3TZ2Yop_qth7= zg2n37v9z=#;^1)ad5Q`IPQlOmmGO@!+MTKDPS8IpDCD?>g$4X{i1{O@CYq5CdH&Ad z28BWMw1OlE^80rRH$DeE`vqgODS@quz_9iEod?{Ugh{DldPyRj`uj*xpbY{`C^g4$ z^TGI|MSIi_&$mBHReip6!3al<)xt5oFSPJ*Q(u!)h{TdW z!SjOoyIGi00Ve>Nao$VG_a^RYge=?W<@Vqs4*Q$5v@{GJFLw1) zA89_Kazhqd{({9`1_%9nHc80X!ETS=&yHs$ij88b7nv?jD>PV%a5+~ipR!?~=K>ct zJGIMK)qQ3Va-H9VC^7}Pe|x@M#E%Gt>WOZpQWymZ@XvLTBX_65YBxW%=TT*WTZe-X zB!gPc;61rA8azrYy`lxT={b0(U-=SR~El)>#N+U443Y& zuU}vh|8CRZilS#FPBkh=M#5;Me`*xm#AFuyyS#NA6aEPe75_Hg4#g|v9*yHnF;xqI z0*PYexZCGH63-2rwiD7#@23qPysg>UzT=tvlXIA@f-bH%lg;(Ii@2;pwoh5{80YTJ z>~ki~5t)u0%#{pYopnnSMOiI90sT6o043IC_qIG1!b&1csCs547O?pexf2B)!^Gc) zjvh0iKPCe1-7%^CKtGSXFFG9OgBavxT;k$jfIEphGOPIj?Xj66H)-$Mk zq;W|i<4NO$@fJ$5B|P37R|O?XHm z42Zx`Pg&Ta5BMR#rjoj5hQoH1exU?`&xh3^tEFf1yGOEIvh2B^^UAVk%J{sD>56(^ zwQuR(x31smCgB5&`SjGn!lmK}%2_WLASFp%oBZ($6Gb8%%h)==<D5ioQgN9Bz*=<%A{Ig{mK3nMGb8+w>N*0(^v3QKW~u(RwK}@hhgB@POBUcH znl5BWjapVztZ(`zTe?T0R+5{F*cXH=lR*J3)pTS*lvP!oeepDAzI1yl)q_M?t1Zm9 z`3Xlaf{f?ay2ls^pAhxCB+|bN7stnI+#)zgubbR`H733qc2yhOSeI>}cxTBy+-stC z6(X$U3HmXRaH@H+N{(npWnxZ6z}jkr5T)p;C!q@l{q?fOb$fD*C+UAfw zbO!UIl5rMF7ml2g@=5;{kbASVu&`^@ve$(4e!m%#FANq{x=kO-YP$~(@$14l(iLcE zXvjH%BE|w60V?ixK0`{y#uidCHHAe+_JxP2Z+OPY`OYaYbmdG&{?%rT#NCoxe*Re* zbq5v)C~a;QE~W|{BmCu#FF~RfH4f!(nKE>iho&Of^$wn2yoN>ZR}rt9)?4j?`u#z$qmIJ;-31`#<|RZ6b1>v9S__kLrJ?}wxWJMP zez^$frES5dVO4H|FM~y#;L)^nsB@|27+fJe4Z*qofW-e z;KeIe8wuz;NKqI#zN)>&rn21CtGC=Zr4YNf^$7#$v#w`IUKYFP42Wxo1~6S z1ef)Gw!$H$M!^Lth-GrFtBHJ|q6HZC!^6U!$8DZ6l9Q5>e5zcZf9Th*xE%$44H3UU;^%yUkL03){_-`1C_gj;P=4RekxllB z@#fgGay~7ir9=0fSKiX$_OKTYKx9HnqVg}nST11^aX-I2YS_fc4MY%nSNB$91Ef5` zpq0x5JIC{eyLAG}s!8enQ^Zg!K9hJ}&-#T48szxAth@8ey9^sw@h?~R4*)sF(JK!o z0&sr5EX&WVuS+>PGO23WgF-?=s#U6NdS3C^bbq+CwG*)gj@>%AzbvrPzH|Y%auke1 z=>f8>2)^*Edc)G>;PDrLF?HthZ~%~%TGjkVN`RKYP9D1rz=>6-sqp%4ewUo3gTkv# zxRNR&yvPcql|}-x{EjNtEJ&4`lEJ#=vPWATKvRJ~6Y+Rfj$r8HJ@AsD0B1Hnn-We# zYkz`mYu|J04cB$co6U8@8SUcqU)r{Vhy3Xr`iqhEx1=OAcoVm5EWm{fxvype`*~oP#u#Z73oJ)F!laNSBFL}04D0n`UWRThVyQ-{5uaGr4P&p;HyD_Umn?TZi+-jv z79xJW-K>GSTl5L9tZ0lq>x!W0;~P*0QW{3{A9;MTvW9`9gEjz9roWOW54&^faGxeD z{rzH2xX1LPy;UY5-drv&y#mUSlUb7oVC$Zz(mf|P^?NBa=WXo(isq^Ubp*pz%^3FK z*s|iMLqos4S^-thCoM!KVd#FFS$#u6VJ~c#*?dR19s_U>(m2%NRx@4&b8qMx{5AO{#B@*xPy976q*fIe+@BW^ibr` z+2EP;&JBzVfwHY|JRyJ~npYTzj~Wf<>zlLXfPrwpvPiF7M=#l5#?ikFG|Njx?Tp$M zuteg1MI`snfrs(5w@!g}6W^Oe(&1Xep_2EFiwNLp}G6;vbIHnoX{rpkv@R$U@oJITVXN=LWTCDD={%84>1S$9ki0gLj=ks57TsO{| zH%<-P=VpcZow1iTn)9A0e7^q5^-TE^VQL|w2q8)%d8P6It4$Q)koUX>!@=#X+uCNy zTC?8WFl>?}3sDz%;AcD`07lt93RM)YkHdNOv$jeX@TW#`(7NdcXbyUtiyN!dy zi-a_e&Eoh}6cwbP^J{1-=I8UrxergcXg-nkK5B`Wb|~YSL&8aZOeynl!fA-%hYh%o zZuHvx(ZH3%wyX2bh1q~%*^uKUNT&0fnKft7lxuG%=BriuuY-HdjqpNVR9Q-b<9GF_p-)b^7ooNgGVokrDcb=z;)ib=N;& zq~-f!>+o4tnd|+}XxLzTB@CW8F??)OoMm}!hnSnan~Cm%vL9zDaUdfy>$AoQALs*g zTuDjEcGufwenkb$pRJEeSHz{;b{sd2GrO!+v7=Ax3?6NoPPT&+jgu{aSm&GUJc63q{pWeDPC{ffL*pyx@1lWctRO= zKOrabFK zoxgBBL0&GMn4b*Fvd7eL%~cU_cy|Wpm|Ehg!O1E~*h{P9iIHkFT|B&Vg`S;GkW`G5IDKb$Q&E@`{&*a=6& zt5GMVfFL6Mq`(V%B&9C;^I=!9KvC!kh&vP1%!;xk~F zfw@r&@pUhn{yR-|&xXA^ikod`CQcGweAX6^sWWs6XITM|tvj+SRqVL;@_V{mr zRR{B}Ot5$`Emgb033S9b5{HDIbJ%4xp6Mp(yggYe68ikp8~P`cN7G(PdWubB@uMKYK00Kit*=htxvr2R`+Kno5d4V@6L zNJ_oPrCB;&mbx7mn!BU%VSFrhR4LVK^Ya7ZeSKpq(vt}kL)HO`0I)wrU0po2KVp{s zQFzFN9RBTB=g!Xm3A1dC5c*>~JgZ4an5i(?*GUcXC)YiU8dC#y|t2kemssoR-!&aH7AbaJ$zD$C=e| zcPE2~)DxfBRGG+1gPBKy62a=c#ZlNnz zQc_U?-75k(WQMhBgb{b^>sl(+Iym+^A|jxusHn5uLIlL1P|(gmn@H>0xil~0QLO5s@TyxbKWp#FGZ(JI&ONrHc#7N zn%#^bH!ogZO=r$^Hade$Q=L6k+U?{tG=;zdLXpWB&1Z?j!o&L~XC9c7bsFmdC028| zNUid4dz5U$C#Ihyx=IspP+dO=`swpr1YP;*`qm<9IYVU{E`) z889(15xKTq@np&$lRu6f;BtJNQhLBzOlJk|+erB;I)j!M=}()9;oYZX`=3)nE{Uvy zxPk`o6Tl!Uj4Yv3cp^b9F1J*FD;Ih83P2n98b#ROABp!8+6rYX=U+9hZolNrazDf{ zM+DQQ8=t+tmOe4M{~ZEY_luKLQRsgFwFC_q`takwq1#pMb?}GLt^U@y_^{52f!^Pl zel<`WGJ*Y6zqq)V?PjxDMj%+pON<7KO+ZnvAvO!nk-+hjD7|#-WmV6IN4bCp%=H77 zod+~vTMOkiev0(Rl@5LvdCvU;`I}WRqa!fB*;3(&M^}y6@rz#HAB)kD!<- zTf57J!S27%hQ>yDU0u41w%$OtLetwa8I%Hwid?|sue*N$1ElY)SM+wqwVE0O5dw0l zZ3qwE2Y_ime{75fKyMh-3YRE@!(oS{IkDOA{wuN3704H(Hz5cM<7hn z+3G@=$fB5>6TQer4FkL|YVUmeo-*wmRXdF>@JIaRSkhlG796jNzI%Aa)iB2#20K(j zF-2*eA?nGB+S-u=2DvRQDZ9G{=D7^P=7iFyrd&_RIl|j1hwZy?8hzSfn!o7%wZX zzPtdjpyyPM;DX}f>K$l(T9Wf@;XGvc7*Ng2t0^xJXU_d8V46@MY)1gPP?jU`zCjfv z_Pib-UG~9$A}vJW-7G>$P|3paljW?e2Rp`E>_=$W%rBu&1V5q6WsuS;xOe<;G&(rN ze2;P^adC0P%`%{`#KpyxR97FRnr7v;wQ=_8Jv9{Hy{UVY`d;75Yb5DdN2twX@SJ@9 z6zM2}{X?Ai7N!l-HmC_cpI{(jPbrOaSpsS*tZ)~ zyC*4$kUcd7zSgX8^C;PnKDpDF+S+#E?}J^oq^hL!8`|dPpB-wxt8N8&6LW1IyK>re z8zA7yDWw2EN5Zt|>3C%&IgwVRAo93@eedk*C=yC5M7L!?Gciwz%bZq}T6FD{0_JWcDu&tL zhx@2uF+2|bSUjkX|Bh6T#ZW2-Q+Yf9>!`j8Fx-}ujOp%vV2t+~a@S2B zxYAvR>iJv8SXcKW(JmL->R>eS8_!;9f1%h(I}IRZD^jy3W|y!E(k_%yNkhL4>){GB)#tkl9;^1u_PL3rjDg* zT|AR`?)U3{etbRjaBL0^j)cTS{c+qt_Ct+`ll**Ndjde-0^SX6tTEt_vC@p@0?-1G zz}b$cO$d)Cf5T0|p_)J!ztCh8g#^^@@7mn|@mMNn|3JGBk*>kPsASy!y->a&u3udV zAnukIdtRo0k&GAFN3=QZcZK0_xkF@%<2zK&ma30jWp&Vrby1Lr02rINWhnb!763r! zS`#1E#>%J~xbSb8lf(02a(`KkTI?eJ6whHV$pu3r83O%Hf0i(%1A^ZB)hUTaa}c2A z?B1MhhCO=p*Vp~6a-vjmb!EGq^Bj3T*&9Y792gi_ zcR$J;HewtxY;-zNKte_a`i|07_cS3X5iyyWqjI~FMSJO}V2}>R<3R9ZZ>7~aTsbT} z;qo(qQ*mQ6Hd*PIzg9#S|7H6XueirwRy5%3ClA*GC|2_Yu1}9%FrU!scqHo9hL30F^VZ(1)%$h;Xdgb0r3mYV!(pzIgQRTWiK27xk} zIdP)a=}39GJ7VJINo1NR%EI*T;b_(Imu1TV_+rXUX4uo<#w+aVU87r{VWRy zM~}lVZfwe!KVhQq_PP6WCi=NV^4rzbwdXQs3{fO@FfIDpGlP6pCI`ujn3R+-jPUL0 z%Jl2=<9xF-U9ngO(7FRqlUdy{n6;&hvpi~+4x%^_$YDUNVCXf~=;+S<#w7!qX}-L? zyint=YZ!3SfZc3p1U+qBuwY?Km3oa&NeR)Z7R!a$YN!4MP1kvk#L*udui}K<+Wm~B zm{nywkW`dXdN^}lrlzK>52aY`A-NIWTVe09ct7fQ2A!K<9?(0fm*AbV4`E=H7pYy% z?Jb|$^>qdUEPj9ANI_B2oYyg|td1{-y*>FblCS8X)g8UU8QA)pc|}(;# z(d@gsVjF%05FMW#*NRpadXys9n9{}l^ZHmO;ppst0p$+~`=_u;6Dmqd_bWHm<>k=v z6x-^vX3QaZA@~p_N|Zp85SNmIS=%{x;R1vbwOY*|fO21Uz1d7MGwapE+k{WuVp{%{ zY;T^&A!ocF4L=q8b+HM!s6UxV=yD_Fbe4EGS2|pJjy|f9g%LnN1bU9{Zcgu_YdT*A zbGyg%`|m$BjC}CMlIg&EXzH)k-!wbA&+xdLU6F7$T}t;}fUrRgO1NQV?Cj4xtdyTC zG&t6<&)DA?0UKIDOA9+08wUr6nS})?_)vw?1j;RDOjwP|Uxf;x8#cv2Its`UHCe6n zT{Le^0x~Cs%@()1>y^@@GbbZkscS?={*Fn_j-M}Dv*0jXglu|;3n7kcb)f(=zry#@aDkI?r&3a0_7WvBsAF0J zL?&7LsP0P72v0oqxhuymW{}eIl_^tc9K=%LX1s<^)+_2jg)MfC^t$W^Tw9W38F zJ&jJ4DlTb;6a7RGv|yxFp8j;O|5T_wSMiGabAe35vth+LH$9CnJ_OJA9s@uDVEDmt za&ciWnZRgNCLJD{{MRF_t#g#risu+?H@N{RN)}7ItXO_wh2zL%_5P-ec^HL5z_Lb5 zSko^$rVnL8A!g~-Nhun*Sz-SQ@B>dnz?}zdol zY!BIT*D2{FQjhc&@X-LqMLl5z`5UpH#B)LPc>Ubx01}E+*G~h7YZ>ETa$dQ(m>4*V zueQ)fs%TmzZbYadwxX&v}e0cmcR-%$MV(aQj|BBCfxVIig zfmCWZA%|C6+0t2IQ&UnVm+S3q)K@Uk6KsRIjF;Q>3(xa4y@lI%cU7*M%qM+LWVvdW z^X1<0RHpta<61R9mNSBNW})Fee;*@zd!9@gW*A{DmOa&}%VSSuC=Eq9!k8xC$$zCC zccFVJC2SSyo1&SV6S*LbGnaex9BSt9Mywa{=s$RHELrJ|G<>jsixBuT&e_PX7#uuz zK?}#iRZvAuTg_*st%YPYk+BqE@b7pzbw%L48tdd6kVX{RGfRxFr%QDZ@Cza$`O!+KC6FjVBoxuH{8H;<_&3LR!YhXm%O< z%m^?Wlmzp+T8$2`Y`luhFhU*LTtlzV)g|x32I26;j2xqW2+ib`kd#jneZ2uBv7`>y zL^R$j-6hV^?m)3btLG#(Y34JPL}Nz5eRz17E;R^296oJw`0J~OgrsDuyDOAp7!*c) z_Ec4}HhY_wlk4m9qafBp5)`k68!prw#ioc#&1~+Payg#aiv<0`L@+1Mh2x&>7#o*MZ7K*z*uq5 zah%!F&5mk4CA=GMPKN?JIH_S#_VnPso&)e6%}O=QDDk!fU@EFIF_JKh)D~b>W@R|~ zL1$mJD?5JU*b64MkiR2h_&IQ<-xRKWWz=fs{{#BUtr%Nf06Ywisqv0y4T4OD_KOtop;%Y5{>}CBmyPy@j)w6@ zW1$djnAGn$aWY^=#!)%q+p%jOqr_?fWeetl8mwCO4VcoDR@stmYz>r9e59}4xby#t zgI-u&9j$EMl(4p@c@f#c`F2!2+?Rs*EK{Y6zM0Wu6DtXF^Y-!nQ0;qgGlX{pWPjep zHW$Z#_WI5f0C6oEWeE<@&?_xv=GGWjd25qEOaB z1IEFL&C4w$T5mFe8HLL;YFXVm*tn!Kmc`?_d_Rk4w$%uxey1M;2_cTranrZg@wy*C z&U8!Bb;(($xYsNJT4IH+7TgCKcr#~-pJR|Hc9JrSHPETlgeD}aVf08Wy9n1K6Bej3 zfNt}$V*AQ%Gu@%)(2AWYGX#hSAOwuqDtu$ND@T&?Su*u%oJmeLuo&2TMAD8QS#U3m zBEjKsa5UG#{tJepe?~SdaN%UH^(ZS|K^O@M>GljwQid+OEB7FE zNT+wtq4o@q3y46o1!F`4Mi(FptPU)pyaMhc62LI*R)>yBx`rL%;Uavb&)p|bJ z$Yk?QoZM-@AD^Oh;G%gLvX17u6Bn2;*eDQx4N#y@{3>D$H$kp?v(O#%0sj#O`JfVO;Ax9A>y`%`<0jfys5)_tANLt zXAhAgB_bgSe0+2PSl!!#)biDn;^!mQI!niu7z3Nyh^%6KDqqEvAs_s5rA&tnp7tSU zTpCu1Yq@%(g|cvI#Yw|3a=0v`OIeWZqzpm#?{HD7;`TX7=RnY*(jQsA=b-BojofeJ z7AoAIg8w=J`wU1X8{KtB9@Sx8;Tw-?O{#PcWu$jckg<^E^Xk$MpI)=uH!tR5db9Xz zgy%?pZ$)yqfLnqe*$o|Z@wxejx9hWbdgo9@o)JN4P9CChZfa@Y$hKo;D_WS4n>6IQ zGALLQi&OcBay8;wq5GFn3MhO(b#pQogu7H-pVDN^W9Zo_L0lsulAx|aS zL}l?G#r0Hh*TWO}@KC@q!}YB8Bl|+BVYuY6C*565f6|;TJwS=b?x}I7;&|S1Dbis{ zJXzsQ<9uyu6hzDDHy`poL@3*d?@58Z#l3}a`1{xB^Z7{i`K0au<<~C-1%^;2|QZ`pr(RS$2jf{-gn+~K(kpdcJ@7E_k zzODHuFlY89_tHuR#=Iklt@0PWM|buw5r_(1%D&q!9;F=XGD1RRut!?tAiq@tO8yvS z{^-={MaTzhRp6f|mnR`VZsNRY@y=k^FRU7fEcr9j`Kn|YWI=H@f4lgZlvOJ3VS;)O zB(JZoQe_?fNjQq-1lwGt9>eq8BQ%ev_wRLoQdD0&qeC1YcpD#1Viv<&mf;T@8JR{2 zXtQHU?^x}>Dgg`EsaCbPd|xrmzPX>1Rn*bJC4l7OTmQQ>3w-)7t%uZqP@AM*4>jc@9-$tYyIVYNyU|TG zw9~KGg`L@a+Ke00TJ$LaHUN+d05Z-g#3z@RgBFdC<-b1zE;QNSUaL#kS4V+xN7ab< z_ODLxd~zc1d4zXfzQOa)lWZ~z8f@-$f$$NLxYem^r&xXU(BlV6X0TWg?=Rtojnn;} zAsXxwM@B+O1wpq@^Wun=t&s~f3NN1+GUFI#bJkUP#p{<3CpNtN@*DI?rbIpK|3Nfw)|3 z`sXk~I$wsL&%=zLXNep3Tm(UaYjcETX+z@qa`B9xnjwLX2x2JBTkpcw?N;?7F zA(e&A;k&L!KW)RhQ?Gg5)V$ruyk~9uZ*B2!b0=i=0kyUYvbGBrSYy)p)_c9~6c%hS z8;^vH2_^)Tk^eUzKA&o=cORY2M_xW1)XwzJwl#+o=JQ$Kt$H({-6cmDSK#qShn=e|W9JahQDkv%nPRGLvR6V;xKywe&VL0)JOF7e};8UBo z0&SAX?;nu%V3I+7CQ0(FJpLNhb9m1?hpyYb zc@t~<@JRc9;c-6NlBCTIT?IGT^8K+Grl0J3$=+@d|2}h@7L_7AGEHTO*{YL`C$wY5 zSgjqw%>X%6>OJj(dGU-TXN>xLs8Xj>gHrG;@?@?U(9DQ(l^Zf0+81sWCftuMF(dY_ z>Ngx#!_E}U+1!0!@0~&Y!SFx}S*a)Mg2vcR6E}3<{T#sNT=;j6Rb)7Q7DKTx>>-Yn zT_1j5ex!eK9@Y{hkZ*K{lN?*>C^>s>AZIw|@Ia?SL`O$=`j)(Zs9dUa?8Ldcwgy=7 zkarFvMvMs(Br?TJqyqo(rY_a&0rz)g2by9t>xMig3v?Fa6eHVv63`AC+w9Y1fTryz zfft`yXV|*VnLq8``wyW#$CrR4!!tw0j2WZHD;t@Z4NuPKOU==nNPtN+#?jz4$ZsHf zO)Lua$ErAqN~4!%z1O6Fz4woKIqVxcY-PjCSSmT>EXF=;eC4&jphs3ylci7=B7*`U zWI)HUOmEQt`?eVNL(wB>@;*p+p26r;P@#ByU~a}g--4=(=}jIEBgo)4DXt>UXoLK) z()TH$8UkHrEuWVICs$WpGl2q`ABAwOtf<`=+<8NxLr&PbhAdN6YlEv#aDyM8oef`L*Cd&bBh2>aaak0gKv=DNEG?i;+ot)AcDMTvY+fy1^M za@q`CBQsPhgA%F>BhK_U%Ey!^$%z3UK7V+zZ}ZBqb=JGIGcs_qPxEy-7}U zf&tkfzxZ1*IJ(1Vm<UyFKj9S6Kph>(Du5WnL5_-#bxJv`$gIhh=s) z+pqUO>oKABrxyiU4B%^}5*41hBA%bbVgHChE)YPhp~47KA%yDWqBDcIDTFw`fHdm< zlZlYJ<6!=S3qnr&9J zUAhQAo3Y@#(p#D|S>@`C7+$2e-$jU1G%R=jRUh!^f<`l;&93F6W#g;Ib{nv?*Kgvy zVVYShgXg*gY;*<^V`;Cv+6ivsHs_T)otI>|4 zy__(f(s1X)wMoHi1NOVYy+S!9C1pX8$Hzcp;NG%I8-%PTQB@Lh%37M8n?Z3tJGW2N zarHr3I@dAt&}JWBr$QqD}c>ZS1hot(~29C;LAh9SR)>5rc? zcXE7wE?lS}J_Mp%rN{lxiuLX=+B9y%Cu1l62d#MZn%J2+G=;kN5d} zDzxJgAVmu5!^OqbdNYW1a@<0%kyrh4Ic($y(U}q=Yr4EL)= z%9WVp*A=w5d1{ACNdV|vm2efF#A|E(vNRdTmVQ{7ODQU&l?%9GmpzU(pO0U8kv7^L z(@>)TP^|!kHe<%DP@yuZ#|Y>}V7V<(DX(3-SiW#6#bzZ>3TR(AoF#!VuOM)>XmZjK zlBUWN4du1gtH1E*KYP4scEuEzgQjjHYU4d|etW*(Q-Q;&&rNv2C=2Z4W+9@Jg``?} zczw^Px+HCbCF?@ZrPR@OihvgM*KFSs)nK}NM9u365 zUqqv#3@hPGe!(0xdPf#Sv?rzGY4uB1C+g3m5s_;7ecbbM7a102Mq>Nknl$jTok*}aR3a*!{>d$0^jC<~O%3rqHrofnI=`pHNL9Dbn*63B z1*Q0DlZoO-5C(eKFSa2d@eQ&(r2tz6^C#Q5=5T}M(sl18{2Mok2CT0wwPq7_MWCfF zI-?UhU&j|g2hN0BJX0*zEMnZOeDl0R*8%Y(`NlKy1u)xayqUn*3iG`9?q2JEA%Kj8 zlqWi;O^c>d&O*&QySf^tQhuPfK!&Z&5RRBkA{kzrJ1A_a&1Fs$H#{zjA%|bXw&``p zY&djEK^|h$&&=k0a~WlF4~2K4F@2U`gjNuQstL4fN|)@te;D8=6qF8*NWaAwVhU8_ zQV@uU@J%rX%YA#OT$87lrvt?)41*VBebUn6Sy8V(ZtR0(J21Oh6Tf`+5m{~4(H+MH z$R9WGQiOKVoQ)=4NnY)j^k2-FqP%VMZa5K9D2;f0e*{%wW@`zXVEa*irI(2Q+IecZ z&fp8!@_-9e5N06$sk{ndRCYZvY)~7Mo{mK-;&Qppk+adkS0*nbBeVX!C^v=KT%kMU z^>NMizm!&r1GhIPFsiCJE*0(CIzYOT7u`m=QfyaulG=mg#s$ffOqe1{W5_FSfZvsC&fCHYN*4xo%k-{Ug_w za+t@q$oJ?@jrHIYf{|dni;TTo$?7QY%R{N^uF7r%%ZuvJ^c^Tg^Bo?yHQs)FUTJT~ za4iqJaeYq#j31Y)SMV>DjIh1_NG&=((bVlcI*;{_$lL-F)BM(573O%8S#LWo9J`$G6<7dLTGf&HeZ7Db>|HXlF z4V09WU_$VFY2Q1K7=j2jJPXu-n1wMADD%ce%aGL7*4`kRxrazKM7S>8J++S%eR=rYFiHkc-d3fl45+LZ* zr?;;*Pz&jv{UXwRqs*tqo;iOs;ybiP#OZ!ya8+ydT&aAr0fyy4B->`r`vFUW6vjlv zS+(iYvpx6g>08B%XMyGYsXRr+rw<}gw=>u6`w8~fwQa(e5%1(>R)M&{ww)nYFxFbF z2kN-Zlqb#qvH)o;;izL*{p`f4$Sm1$PP?d#3pywU20dUiaFEpKjkp5w=yo@c79QFF zYi0O;W+4CHGz-7>Fh{r_m}vvr_T(-D7K^pU)Zl+Rl9+uMP|% zf^TmfF57)YQijakJfM*898>98qeGK*MIGu8Q#lb+Dg81!W+K|o1y5yx(eb$6&Vb&{ z?tqf2>QDn7Fcb$PPCcB=T%*%80@980;{F%dOgs!Tmc|=jRC;daoZoUcA}+y$+n2aRt+6%=*3j-CNNE1_HT2ew29r*UD!y zpP`Qp$K)L==|)1Z7R9uZWf8!3KIbdGU#;iXq+SpoFEF6JRKZW$KPZ=yD+jEl_ZaX-hi?2m5xvx%fQIBR^Z4 za3`5~ZQyit7=!b9IN<l%c-Q%6z8U77 zJMX>9InT5A+H0-mMzb&V^ZJ+1OvM!;qLPBlIsNWXEa zh2u!W+v$aRygKC*h?_T)Gc#izlyo`PTZv`CiK^R~1+7aS9{lt{mB*9e?r6}^)8w>T zT$q0o=zWvE3&TFcga>P`>BZhwT;@G?T(Wc~$WQ)zOCoz0O|;|g#IQq>9@-H!VXs1l#iKnn zG11de64=?GiGDAZFc!bj>rj!zBe~|I?AH<|nx59nsB~!9AACfa_WO zJ>90FrB!Q)wR+Mf5VEncq5I^?x6j@umNfI&GLArztZi(3gxJ%XYs{&H)U>(KGTZni zck$}Ko=f)}8P4fJ9W8)|0-EPc<@%So{oer*Vd8FdI-5qZdSAI0i+ z^Qv|ON7u9${Dv)W4oJ_L#&0otr2GAOv8|zfS5i`T=%4I*zb~ z@+nx6%hF!k=gza=s!V0ko0l=(E75$u@+aLlXoYOqS0F=^Gfa`qi%IOSZ_`m0tyw2= z&1PO{DV`e1kAm_RYNtyc598gs2$S1t_wL;@$<7N}lt)nu#>V+0w%Vqq2{AD-8Fsr~ zb8PKS2oCJ6TeohBmb`CjLZLk_+08>@Q8npCE?cX&$P8wyx9YEzeSCbn{|G~k%|k`N z@o7w#GMAe+ro&vGn`$)k?YJKI7j7mJT*!w5F8)3|)pKm`Hl$x7xLZZ{yh})ph9ST< z7@>|<$LSZdYrtym#3-6Y_y2AY^Cx^?_qOqiilIXDYtuoD1&v92r71uix7xRT~{?UR%q3 zE=|k3cN+DN%xiy(gXqQedPGh_1wc4!HbFj(K{^_){DYrkc;Zgx4AO#@E-O zKwPpIv^ZLg_qH|=h9lHR{cfco?CJ-%-9u)AmD$Mw{I9w`!X`7iz(GIry(9Vk7rUD) z?{^kk6`z37M}JpfO09a9b& zQBME$(s9QU-bI*X1(|uxG9@C!_*l@(fswu^*=8~i3ER~4RbC!W-h-^ z3TN**8#*vHdvTZP1oM2ao2!UOR$e@z**E!21fg7%?ImFPv!9+Tq&o5B!uR_nG*&W6 z!4QuFjY^jTcB(IfgR8QAAB^jJ-$NyCz-lK%p-Ooe2^o)Uhd|)@Ao-&B+W@jJ+J3Su zum)kQ;YR2iS^d~g>H6$ka>O4U$oDq35$F*cAH+RBkjl%!-tk^1*MccgFtBV8_WnFPH85# z9RGi2&c2`B+uu#tS9|QuRGHVbwlXusbK3U$AhbD(c*wAXHl~VeYpLLSbF`7S*V>J3 z(enU%nOLsd>M;GWG}s4#f3fE?VL&0n2(j`7F>hLo$A?mM)k2lWC*FcR(HtJ16TZlE zKcJ>Ahvz^Zj zyWorV*-4BXd4hi3r8}QGOQg`=&c~fxK9D}G6!BW>z*SIB1uBq;gkL@>{N^oMWJ z_=G4~SXzUe7@FGE2h|pC{JfCM=m>hrryL`J@8D8!Eizu+tsY?CfWYUsck!ws`5k&w9fPZe?7=^>H_R-5Bj4DHPYW$Ax38@$EKVe%=V1Jv!`@2W zXtxs%a{7rW$3w`Z!u*y-vwdukb_qbp4v?wQ&dO)tFou0p7#V`o#18uhpfD-VedYW2 ziDjfkjZRV_`a4j+;EVUJ4@~e;ccJX_DJFVuz=v z@2>o_+-C)P&Au+AYq@>(XgFR3B8&gVc*V+*mwXBW)hNHZHb|Id_9Y`qKx@qpAiEK7 zd$1MpY&dc-9%t@+ka76g&6ORr!g_r zM>GVJBL#CMEo>JF?_&fioe2&`-<_()gt;$n9-iRpHkN2tdd)C=%Y3rb-pvBP5#o$j zH*vRX(TQ+cZ4rlOPG&s|Extm5SALRP*<#Nb0Gp#&H1oycH)(MGT3%uF0eH>JD5+?m z8iC<}F`Q6jVs*l-u=EFsm7jO-l6xi_>`#}f6TVwYHA| zybj>=a(W4Z#0W?tF{70+;0NM^{)}4u%Sb-NzzI4m9cUV^koHDhX&Pl zoQfo*b}I=`!j$A#0r2T0Z5%zMhMC>@SaEapF}&@BH_}98f26 zPxcm57B`iWJpJ-*s)HXNjCFK%g;%^EJ)hkel2G+h=9Bm_G4Z75&QWta8X68}D(8I$ zq5j0C&?E$YY!Ah&E8^!Jr{{jqovp3dU0Py2y>`LX%Y2Q@mBlr8Ti$k3*<3ylwB{I@ zn29|9Ge_iVi&iubUz4PK7Qg;a%tA`gH|*SREh&#yVmqji9ZUBv)|!{+!`PBS1{f2R zFfev8IV#*tSQfQj!7s@ZpZ*+=JZ(GW&NMA)w8Nf^Dn<=tW$7Gfv zKPsLu3el7C{fK&on~%f5LlsjxV+LmhP~W!y{io#N;nDpkY>)NwGGN-jOpoE0B^Cuk zi>Uydw2=R|6u$Ylsp|aVnc(wZl;&JzOKv0`A1c*`ifvBoURWM?dLK^XC`j_N&U+*= zi_8DL*zwU6Yq$KD6&$gOhVvLLHZe48jVkafYZ6K2>8M5M(c+p-79pWi6FzU6y|Uay zz=l-P?JPN)<$qQTgab-#*)`SzPl=z|i>#6Be(8ym9xSBhZt0ClSE{S|GjOT`dY;Gzp-Y_Vr3R2;C- zg5~9LcOWrVo%lvKIkw`2PR$i^^JTDmMh9bU;Y4Q-l?yu^KZ&0MGqN7DX!1pmIM#&} zUSuRklVfd`kIR+`U^*gYJb5Zfw&{S(z9wq z( z@+vAw;7Rlk4t4?2do*R0*a1zZispSq8yim3z{?lX=WD5gS>L$%`MV)VeSdQ|6imEO zeGIS7Y)>H4;r~%uOoG8j?edAUvD_;vDv5L$=z#>Dd`PKsauv`zH2G^9K_~DvhC&}+3zv7U4q<+ zmS=zDR$XT0wo|D)PsX{JS2eOmDTvnAE^FSSWiVp*n8)kMfB*gPBm{*}7`KS*!G{{q zw30S7G?Xm1hukyO3z?|*a2#fjw2h1yPA{v!iZHJCT(+m3U2%R+jc^9MAt08`)Lq!_4vEi)bc5Z6gcnw z*IcBZNYk=h9AbX2!+rc|b8S!P<<8@z!F5=fp_4y}SLD)Oz6^88#~91c_op7=W`HLEy=mfi z{@qs;DA$OcA$M605*fhS!ql;2Nt``** zEtOZc#$@gj|JS&;y`BH?(@|6}c1Vnx9xwIhjaj=@v{3Z7qSVgG{hAt`Z_O?&_4?w& z-xneJ!xbG$-xcr;9_7J+1?bl1!mm-I2=EKwcMFP&x_^s9EqT(wGt778<@u98b@cTk zpsvkpXrQyKrh^j+PSXW{Of^j+A|mtAB6Y9*#?30bF;19#$S)|sfER0MXjuB;L%4o< z@#Ejx9C%-kA$sTieq@i!ffsW7cn{2|`0JXWaB6VuM)tyQSY;Q~m4VZC-C}#oc2UM? zHBXj<49~pIh>aq;%J1A2pex)|F0J2$xIP>rZFZP2__Ou%rxMi8CZVp}+OPRyy7A5) zvzLSt2kr-9wWEdh1RFR%*I$)4*!7sJ@fP{YOiI#iC_no1mmovDHg6gkLAXTVmGu3) z0BI^JD0E~*BXJMaQo`S=JE<*p=X_zlni`+512>hSy`PY;O8l9DdVYV(1V zo2b0@_wKZk_@fUdjTF#VdiYi|f01Pil7mz)g2&A~}2>_5_mm7hr!$jG<(VG)3)jE#+LB^#*?-vDYmuB}F6rxt3^R1^Qw`{0sCD;Iw0 z1z#k9E~8dSOD9I2ZR0+CDX&$2y^cw`6k5O7TS+5;6V$+|9o}hKzv|#C)jDQ>v^`R2 z5U}Vkp=U@x`3a)X$izf=*~5~84k=@yoIH$JDR{_}w^^9*eZ{X=|nUwNpDCW1r>fAOEJr$xTaA|$_t)-o zqrdOmRq5b*=a`mUJgu1@IlN{<8vdw%e{jGHbp=Iopp2(P@0_nIjg5^ReH9s!=S^Gr zVeF&=u@)5S7D}B-u}q-|Q(uh|dkAN?_V%5Sn8aWc(uDQku>_p49iN;eXJjA=g|zDk zc*l^9EvV7H){EnN{ni~6m2mDV47D78;p_kY9Vd6FgP-g6OKM(tZR{jHSLRJ$Lz6Q|-7y`on^UCXRDd*q~hp{Tvp zKm{)kT8Zt;!3(kxM>~v8OIiXgVd6jD2TQY|%gD%(KYc72r#jc{E#gW@SRJsc>L-Fj z9xM;8xNul7P;zS0)eydbrnB_lt-=Q9Weg}!^*#={eOoZ%{SnEi!B8F+p9V`hh9DqBQP_DN{c^#{#?5G-LksV9(+lq zOMkGX55fU)xLY$cIvFMW5lQ;Rt8`Hz1%Wyz{wxN{?RaZT-7_?#2VF?p*jUQ`co`x= z6~sRwdUfa_!h$VGkizT9xF7_arE-!mbs(&@RTe%hvRD`Pj#9ohtB}x0TiQp83+iLE zm#<#2+ihq%%(t;Sz#t$EILMW4vqIeUvW~Bq!*@e6XU0e^3nQ>*&3a_|CH&$aUP^-?lmReWssj)&J7_id3c zOyeJdZR+rgTO^T6S^^s<=P;|LkZCvWG~X5|2SZs$8(B^(7w0EuP%<3CoFMk2GbQ>a zR9`un4U>(E0M3Q{vF#9=4X>o+WTBNhg6<3tAcF8iSXs&NY~}7!+1D{_4(0Y0I<>|B z>QZ4PNJ~re+E|Wsd0U3R`tjmx7G zsdlQxSKQQlow~NZz7PT=>QzDdj5_O+lH|*$A9jenc-V71f%(`14LF$Y&D=ne7Slvj z#YaW6bqho4gAW$GXy?cHy&$$Ej*0r;rfezHA2c-B(V|8{E>T+pAQjp&wf+|dXRv1G$SrH9uSn{swH zDhmqOQK|W929bu`Et&%QcTfYqu?uy7>m{rmR~a~1G;6)GqDn65P~^l+fX zHN3c(2z}P5@sRdRJgW>RfwhnAspn4C@v4+BtIw8V1r9IXJu;}!9Z{ulm#(C(ylonH z3zx)vvC-}HmZvo#*(y{q%XB z@%qWRpoBzJZ?EbF;L+OLRH$q(8|SUpgO~q7jADhC?p+L<_2PUe5NFA(<)G>3ZD@^v zRXR)<3_tR=SNV1B*8sjY&MV#cyK{|{;0AK|jNV_??|eO-yt2oZCimUDcMS|5VZtLG zjz-k{NZ}(XYz&33A*aZQcY3_ZZ{85Km}*Vd3yX+Y(RjPLxxuceXbCppr-@Q7i0TFF zL-T5bcFXE5q6hZiF`RpbuOf1hTBK-&*JzSZ53a6nlfBRi10MfB3n0TRE#-N;x8&_g zOD4m6K$+7_#LayOr813g1YgI4o99a_@SK_jQqTR z&)+1x07gG;lY1UxGf!X6s@%kZY_d0zB@tB~3$$GbUtU3@@N2Fd3vh5mO{zzqK2cx^ z+54OE<}1Wsf)%C9vov-9FxchfSg;hj*FBzETQ7l?t`PPrcib0w3JP|@TOfD=!P38e zESUc@_OBQf^-!FoMznBBe4=#7tgh}-Y>NKp|5lX!+;^yMISVqtfA05t`dP#JD`R+> zhu|i#0vt`GCTC&f6)N)r^rNw{(R~wfvyWlN376eD9c0(qshrt8)xbbGO-@Sq3v#?x z@Zon#|DLikX!f`Tfg92Q8N54!Cr@jpw+^TY!XX-;dShH!ZjP5dthS%v{hBRB%bpxX za>jF=Bb?cOvVP=+%0AxS&x(L^cj=X}W5=7jZdFc;vSe7nU}gf7;EW)>x%_%fi4`19 zNSpAkOQ32j30gt?G+j0|BQLYcgH3Mt!Pd!}{ApKz?}NVD95GCP-+t00YRPu|u2&xO z>WW+}>&ANd>D!f zbi8Q{pQ-x~)z464_Qpch zP2UKR8X5$%-`HvWf67qXWrfk+`w{SLfy37=DL z_&7=F>5<*t%J6D&pfR9mY|MBCaS)Z=11AWM|4>U;&F%s6F7M$XHctnmu&iksLXLA1 zO$LNPVy*2NJPh~ri*=W~qbZY+2!*)koT>E6iRhL?h9wCqcDp$G-_&&DOOWY$iM~bu zZY~)AfJad|8On-RWx&s!rUBd>Dhs8jr-xbZpuW}UGFCYoOc%*)Iy$nRP&-1y)t&6YH?@3u z>>0hCJHu(?_H|R$R=BeNc11GH4fOQFE-w6<9)5#_t~nW2jFXeV)zzOiE6_tMZhsjq zzE|yaWXW&%5ep(?J2YoNID%l71eOKRQ88(9$3JMhmetVE5QL%^@*xPWP^Oe*mhCd! zbRsZ`PJ?r@%SQvl7#qWwzI0IwKQj?w3FbOs&?txIE1b7{O1&H=H-@q0lWde+paIp60=jS&pG(!b33R6-34ygmmG}P3|hYy3* z(X7?g2Mo0C5Os;@Yz5Bld5pr=yY^@_DVlfWns@Y^dN%JUZdX4$@adD-aal z$Z7-41^2Q0YnOi(wU{NGgLZd!5wI83%O^CN<{d{jPm&SpDWH_Bp+Kv~9h2kre~(jN zHh zc43BiFF1{s76Q?pmKh>hUP&FJAKv6r)M=#%F}c$^-GcjH;J=?yoBZj6M_^sE8cu5( zB+n}U@FC@oN;6c}W(5c!^wyy3NyrN>;*sLhb9W$t-?{=-$hn*rWD!y}#(wG^lHR-W%3zWWE_39wys%mgooU z=VNW{O9w|sPEZ0Gy-#dhA+A~b`^$KPbz?FnCgvKn#`?j;APL^w9q+%VcE?bmu>JLUnMD#<)V085;3EFU?S>M*+FK_v$r>~zPo|r42b9VXD`p-yi|4HR%^{a-Z z+sDcSmVaG7TMM19X1B3sU0sptdR8RAFD;E~3fb7)Ooh$J3T@^AfI?lJos-75-4P08 zMNphQ7h}AH7=`*r_^{q!AXN1;Iw|cu7?+t9`WXJlEq@j`(t&|;yO}HQWZJ!1?=bB; z5ts{llk(+4JfpbjM76JvPe01}V*iiX3!49GVGF83-aPLlW6_BP1&OjIn;HR@8s88L zfvdp*Uy>dkIIzaY$J5CLNUyniYx67iFpuv*Fy3~^n6NL-EwrS2ml!ydBO`JCh4JjE z1}9qky_BQ{qmY*$n}^LVsd4^H1XC++?A}x#UzB9LNl0tC*y=yk^x{9dKpsdWQ1NA6 z1l+1L{|yJ%(!MiCKK=M0TQdCmZ{>Btqk9Dkx6`cv?W^?z@1ICp@9|{kx&zFCWnv^IqWHJZf<$V(^39>%3lkj z<9lEYVrG3)J;~(Ou8VAMpWAkaVtsVm0IfF4#5`2)j?_&-uj^Ho>!{B(m^Rn5_U>(M z#0e2WIXKB=_=EdF7rl(;XZNU?h~sNtC-Kui16&3lt<|T(Hjrm>car2mhlD&0)&BdlPs)}iJTfVc zB`b%{;$M4%OUv}N1|ofMH8YYHAC}_xUTru?`Vv`iBfIiFv3L_QK+Xk72vFvGlbVn? zV8L*QaeC%_KUlHAr6WruPjHVV{F2zwg>!rva&k;h{m76gESc5@j!bvQFZZ5ilfw`#B@T^qSt5=RDpQrG%D=_Qo0-DZkv2yT3 z+Ch7bgzK!@l8%h%A_5RL` zc<;}4bG>}lFSWnFA%WH-+=&44zWMRmfbCg64o~ERAn)xM`zX>Nzv*mbt3R9Mf)8%R z;A4FS3ba5CblrnC+RNtF;7c!=ohAq8h8C~w6;g%GO5L)<(R%_geYy;j^P#hQz4eO$ zjN@4k0yhu8D~wo_9?eY)B>cNi9A}?x1fl zk#KSA??8#4dFMapvqKBCWg+F-Otqzd7!!94`Ss^C=ab3aaW>j~%hY+iU$_jHz;qLf z&yoG0W{mkyj^ms`9zoIZ^L|_dL-jO&>BRO~kHCI=B+C`Eot@?9tG`D4Pb3M?&+#*a zI0*gypC@Sq8`gYu*&g*qAOx#yb%cs^ufJWxDZ~Xz6}@Jb7~9rVWvdakm%<>kI)VZZ z%k zWDyiqnxY@w>e$)j$H9D?=-Gby?N3A5iXmR#vz3kReupu5{HU&&*IwNuTrP!KKEY6T z=SSeT3nc@dOY53xqVz#*C}L4{8BhYT@9rA|3z(UiS>^IISQT7rZNJmqd@3p-fgFm9 zrUhY$koI=bSa&|g#H8ztlXT5W@Xv91G~niGnYFAna6=UentkzNX@|N%B~OTp({z|R zB)nLm{j*Y5vJbtD3v5a*o5F$>q20x6+KbIV*~mW&|88YwdMwR*n)TclKYzpz5DA_8 zTt$VW=tUdc;ovs|A{x(>1BLKwCh0P|-2qDTb2ituJG0xW*IFg4*;14XltvAdU6(Fq zS}d8lf%NM2i&QoUv?T}eyp73gY`YPx_YK$SWYq;V_u-s_?Z4H~57`{`2{O;o`rXb0 zGAyWTpp{DzhKGHVvmT^J82Za_yai1#Bq9cBas!|0c>pvKQ3W4Lp|#U3pGc5Il3JVK zDgy4_-0a&uWLA%pl97SeEQ3uEO$1Y!Ndwjje31WiHo866E{{!45~QXT_{}Py75ZoK znt6U6bE;;O)il7HFGEudE5t!m?61m-W1Bxc3A00R-zxs9UN#gC1vO7>FZQu6nPPje z)c;Z|TEEjHyYx4oVIm)T-DOkQwl5g=kTVoLNQx|c-M%h={XCs5NAm7hB$FfQnI=tB z{WaP>H?FI*T|%MChv1fW-x}yus5=yPc#^^N4_a%i>4RN6vHAi6=htKsrhfDLYv%ZDRK2s5Gm~*82k2E;9oWaG1CbdI;a`r&cKmvc% z_)?Xf3~%@+CRUdfBNMGulE-Ia$mC)(ZZtvUsbq4JP`Q6J_|?Wuvp!bQmh;f4*sd>R zn6m-mv%^d+k1Z|zUac8?9jG|Ae)%+UMTY2>DVv#@eH}8J#92Ae;O}X4>#dqpX7?B- z00obVhUyj2Z!z8=hf#8UM_W4hZ@Q(K5%-iOVY#9ZU+_}-p~_304+>!WS!r&( zK3D$j;T#!Uj#d)1H%jTwjaTfhCGohiFP`48;EG|useV9QQSM*8#X_n;cdylI{5uEDH$ zNJL6r1OikHs4^nw9gIGRA*GfA34wTkLesq)V;Nc?A>T_13M|K``M)3`;=m9h^nZgv zSzb$IeHrlNfEA?*IDEpoI9pAVPx)pO+~pEE(5j8q1Rdw9TeClZ6~MOwDL+Hx*@LeK zFB_1e*S~zH_ByUU7ih<;KO_)(`h^Om&wtQYD$}#zk4uHi^H}G>uE!S{i=OI< zrj@u3T8FvHtW@pl5zQL9Wumt=aAB}OQBhI*@WIpAf)Cx3mY`}@gG~!4J!;f%2ob7| zP|<2qzkp=~t-m0I`swfAoz}u^LPA0t&jM(0FwO!^T#xl2A6Qo$SeMPv?AWJWSHcyW z(T;#>gN-IO83blag?p@ItR=b1Kl4u%h6vXw!WJrC#@Tfq^7gqlE!C(dJ}R&%{eWp% zfdvw4e{NFZ3VjbMxlEKY`Da&@6RnLUj0@4Ids~;PLN!&K0WTzqUM}u;1j~ONNx~E{ z45BHqziNcYG~PTY&b-H{ZdpJT8rrcv039Y6v6ztu4fr`7RQjNg+B!NW@Oma<-G#!3 zfPg^owiIJXOFGp1+v$e%!d`xlWq-O$j*Lu4&%I&#dl!Idv&UKnH>?rv#?LcSvJ&-F z?6on6bd=nteESq@@Ri?d>OFciap!dvBc6TUv#s4<@cymfwi_X0F^b-%ShN5RbuFz( z-LfJz64kDuFY;c}Ie|}yUgLiF#9}IdUpAg_6%bhWnpg0Vo*r}uSIz~cVXF<_?LR4g}#>dCEszCzRlwu8Jn%;ku ztzjJ}+Vba_6)PBL?o)0ad2#bL5#PGS-!RX7dU__JQ&(4qdKWG(LiYdtcLd4!sG=q0 zebDjmrBElOL(9Ys5ul6h2wQQNYcl4UzTg}4hcw*JRDg;=Wy-}`jLV=f&nV-`0|^oLq@_~;# zeK3^jh-3Mg1*=DM_I_L;gmciWG?B$3$+-uWag0PbsGEFH2iB|GPc(+U=A9;jLjXi{ z=-nsZ;rC{UQHaF-WUu(TRUs+3GD9ur;QSEEoe6n!dxW%2Ja2aui zr|H^p9-H`Uit*I2i7l7pXjZ|1vI|;UhcH2|%)}wi;M_Pz9{Wy?5EINSKu=Au-Geg_ zI!7Q^!%o6r_Ss@H8h?E}#zBK95sMEK zE*T__O-)IxWVGal2b;9|(LWo?iRVq72CPI&_8cql@~7GMCM@l(x4iGc#AJMScS zdMUj6jGxdFghQ*N9|>Z3rQM7{`2?z>vsQZd#G)28<1{lfBlzEs_ZbJx`-I`ZoWebR z2A>=Zm8X564*WR{kfjAwuqc_SKqVFy_3+4uf>z`We77|3Bp2*qV&%8C+_&UI1_(&9 zh-;?f*4DNj{Tf+vH)A=rUcPOH__JeQ^Z0t~4oR^tK3sJRj>lW>O?iz`lLV+$34H9> zc9Do-VK%j5{1G$$R&cuyB z&twWd!y9RD3h?Qi6n&%_{FhjxIAy~y-h&GzrdGLckCHEX&L6O%4Z}rAv6Nw*wxXTp zf*{xhvEqS`1xh&bf{R}dN7PutTk7lUX-#g6f0ZvXLEk9a%y)~D$MCey6iXaz;l;G8 zA+nsDCd|k&jIvZ|s16t=dk~5$VQYL<;scoPZE%^+r~{vmgNs}J;-|j!Q8%T<%jEyU z+ZTa(wZm3ny~?BIGt{tWj)p?pEu>_!yQ`&`eH$>y;Hw&l^G`;r$NJVMWBYRTg{ z+>@SdLCNd<^0Y3_&03fqfIM1{fM6cW7+J+%0o@NRhQ54Je74zdJ^C{M7wlzW8!Olu zLbn4LOTAqVSom#@c6JID7HnWda0oAWRQL~+y`c9i%(lJcYu~eP^Khmxi+k9@OeA?D z>8Mw>hMnSpJEOC*FTKjBJ2zmQ<&%r-4Ub_0Q)kw)FqnZ?gaWpb-OZli7?01VfBw@E zh{ghL861mWrl%J|zl_EO@8%s{tHKwOH*O?$^S&hrS3LBR&d_|D;rQc4Td4NVIu!|v zY+Q@)A5fXiDcIJzW*x+sq&(0Z>oHN69fEQx<}eim9WGdI@B`PQu)Z6J!50ZhC{E#a z9-(4pHM^DYsg^DJ7BE5zdaGw9o-3IXvMY^tlkW|chWw$??eYy9Uj+`fYos7Ep1mY} zIPw=gw5OX_sBi^nzzHhSn6qHDNu2CU%SXWE01()srvvhk$X7st3=D=Nl`Z=oYR!jq zc1pwi8#Ff;f;!BD2CNmKSp<+Qg>kN>8lI?_EQbpR>h5VdlxD$X~AvQ6Aihi9mUk zo`}Bq%6Pdhim7sBJKIp=rs&7BiQf_dILw2as)!`FM{Srg0s1X*zV|r>>}tX zurQDk(#QrAx;-(}kERV#bvPa|J8zFB?;vX8ZCLm-jUCjExeRoD(7-vWnL^**|1y?rCqm%}s^ploz`J=dGz!$EaLMPW43 z4My6Ra{#s3*Ja-B?a^Q<*L#=eG7r5EnAb1PC8bV#Sf+RCSnV(^jJj>p#!|6xB+eig zU)l*;DPRH3==7N!y2U8s!Wlq$C8&t(>#n4U5oC}GWC&U)PMtty4QA>vBCi5AYy& zuYy8ljG)0a)Rap&wxY=V#3o+tXA#rkzwFa-<1dS#M_VB0+9}b{Xm{0>74&e96}p0> zUYCPmRbfNJ)b$G?P8cdO@(F)6U=0~TlyNh!DH1^euVb_sh5@4u(@5_;s56R3(bG^i zq3G$5sA73%!sm8&Jdit3tCm+!J8*n-QUZX-E?MFWw}`N?;PV+#zh4uN0ldq*R!v47 zv9NU)7EI@SettlcA8N}(m_Qz8%aW2Qg@N|^_1MTl00r-(L*mydDM2MUO{5P>7;R3- z&bXw^_iEecpNBR~#3OpsCNiO%EY@urkfQ=5CdSYn!BeTtgrHy(cH)u$l%PP^sE$a9 zQnZg(RT`gPt?pxHJet8uu+%TpgLp$?YzRsQuu@x3RJp0xMMT{6429Z<{0rXp^)lp= zH86%*Letf2DHu0|2*JU@(N8DJa9{a{aAF^0YBK1GK9+RhV66&-z$#GW4a*UX1p&Vy z^Onp`c=c@i;6M#7o7fo2C53bhMvLla<5&9ek<>QA6o3Uk*3p29+wT!3{?WWXi)!U*(lGUd%Xr67=L@ z1|b+C(K38yz^?i?iMt)c!0R3b&O_+m&X;BsbHGbsNEuuwSARWzL0vh?Sof5T0fhyP zERHMQOh#7Ojud2IFi-kt(l%JK!s^cr_{#&rh7f2suu@RX^4WSP+{C`F7-~L9szST_ zT-~?|>+UplE}fsGyPUh?B1Z*8B%R-fiX~_tp8LfO4MnOJ2J4n#siz?6bHn2p-8vWe zhVDmvqco&_rPwp_gdEeY+JNcp4Ecb3>4NKPO_~u2A{?c!RPRkINhx$=!`pT6eE+B} z9H9m3nimzk1tODDOB%ghE0+fbPo8CBUfn=s+T-5=Ap;5K@he;CbUO1JO^XVkLIA0R zx}AWQ7_b@_(CCn!RE)iZNTR4n*;#p4@GnP2VPoD@@zQE z@s1g}KOZPt?_#tUCdx9T|5KV*1~`)3Ga>n1caU5JBLf4_bun8_s320h4KlGRwInQ= zn0pDROS9l&2+>BW!)ITBv{-$>tIa{Hy6VW2rs3}45m6@I+xfx?mLLhxw~%~=hlig* zTOKYLLx*8_&>SO7(MfJdhCv}2#WNzl=tns*A;n5{tgY{%q7^gvv}^UKbCV-qpKqz^ zE}MxMGns4N^=}FSmNxSH%|r4juL;f@tlwN8QaSpq*<^gvcfUO0XZqj~$46MXg^89s zgju$P{_1cN#(6$76>q>8nc}kw4DtbUR7p_)xBgJiLW=Eh8}lN-k6S0zwGjpbU^f7L zrpA{LX49wWSp-pNb)2Vdhwzb9G%n0bz_in513@N*qd2goh!T7Q0Xq40p+o&z|7x&Y^DZL6+dJ(vxU&_Kg$%dn!%#`&Io@@ z=d-;S$s?AoqW95T1{wIx^TD;X2xQKi@GcgnFiw$UmdFnC_CEZ@Rz{exJX!Z8pKeMv zDYu1cx7aEX+EaWWc7Y2NoB^=vlQfEfv^bRzg98{ArC z0^ATh1T2u20auHo7pd|-+0gm(jyvs(V5kTk5e#7iMFT_)WFGI+W;RdqVe|l?8knL* zp=w~dfqLIpS62x| z1owey8tfsI-UOA161rsB3samaW-MXd>kq#f9@f4VDv}-BZ9^KxPlIHp{OBRTKkaaa zGk=JvN|IE;|Ce`Tg(XgKD3$$W!v)^(;W^|WjznU=JLiUR({5*ou?$L}VKp-4;}K1v zxB1qA$5~b5GW=>N7ND$v6A;Q@l-B!F<7qd4=7fDXB*c&k!3Rg_hPkNQ*%~F$8BUR+;^4jtnEv#vt_aZ*ZSz zXB36KO*+tJ$}DO7`C zzm1-**PGPT0S6rF&L6lG7y60hu*Tsl!y7)W~1M&9Jl?H@?II|)v$=QseopkTzU&EE%$iJ*`IL%|s2xth+)0rB5EF zCq=m(fYU$wGXssZ%t{4tOSJ-^2(Dz5qawh*%=~841w7&K!~{0f8qffNS{4pan5cl$ z6%(Nz@iY&fx49@os7Z52M~4n05^^9IMM80)(cP6!ez$D0FLphX&rh!i`SQnwTSKOJE&1($W_UmB9MH%H^r5SKe;!WNO zy;G2|>MW6zk|Mlf8|rm<&4_uvRhWoM=x~d@FrS5EKE9X-4x`EY9qdF@!|ATGFd$dk z+uJVLk&wr@c&(pqk5yX_q%_#=LZ?+h9e8HjrZ14(>VU!qT|Jl^vjFe&5fTyJB*fi< zjr6f?6nUHgJ0Bi4YJ&p@r=@2U2Rbe&XF;{KqM1K9l9A49{p3(Y;_jiGU*PnL)F@U& z%^E1wK}k7c8#cI35Ifr&lG_rCjV9%>+YW7}&K;KE*}E@B5ES^3-6Rnz;)5-PBy7N< z;^L8>fswz5RHf#PWo7t)Fr40&zmeKw$#&;Xnrx*3o(%4n7jP;m0vQ7y!hji4r3wof zb#p}ZtsbGKHsRU%Tp06zr;F_BfZv3oUjd8sYB7a_3g|qnC!wdO?!Yzzc+3F|2JiuD z_V&E~U3~>5d{hKb#FO7tS?w7Lz@3Km17j*`n#6$CV7cXqa#xcww-Xmb^^A4q}El!&Yy&{5=a2&6bW^vh&f3%IU9P@$VMMiRB32 zsf(goi9|S|t=k;yhv>r`{g(7PMU#ytw_(?Tl*6nnUUFe+PmAgV1H1&Y6EJ_S$=8n= zpoEu}k6(NbYNygo8oS{ZliQ^B0Zm>S@k81@X-{{FvmX@9VJOkOQWu3$H&5;qM|}E z{Tjs-t58M%3DYs17Gv2rHhsAr1Vq9+iFUf_)vR zK~Ndu6Lq!QiiSL${>aHZoh|13-HaF_-H*x1`tkl*;2s!U& zK_aglHQqGTm}`#D4$pKQL>4%jVrE+HD{J`gVgFZcFbsWR<9bKxC#RzoOlhOz>6Iy@q-1FlS>DLVQeJB{(uC}92$f9MDJ3Z!DiKm#g|tvHPR901X>h)eKV9ST z%>CTYZ~c6K_tGNa7AAi$B$cuFbY9c_K`U}BDQK_`2%Zjl6R#2-XnJCX(lhB4tC)`y z7rG!k%&^AGq=KYk(#v(ej9l%smj8+tD_CzN2dEGVAFJ1j-ZHZ=GvI`o*|cUtd;7l<@jK z*>Z<<&CQt)#zF$OY>VPCz_IqccrSxy4a%4-R)X^8FDJI$_eQD6e(uM0$N|b3}%GDV-h0ysdf~Yw&xHN zUgUDQQT;9pUh&y?5F#r+?+&;S;u5#f>+lLn>lv$biP5ASOO}zUS470a(TC?~vhVov zlrMX;0ZMDH#{}{WnJWYh%aI1t>m3?OMPms?5gh`yFDoyHX2laBWOhzYQ-8k#NX}m? z-b!IWAg4<&!n7jui@@Plen6xWg*BB z${RebTBPw`h>iMXXdcG1zeWmnQW;dA7;>Vrif&)U%NT`X6e>>-s^jc|@h6$w9rnozB zqU>N&U%)d0;cFN?>AaQq@QQI}P_fSH!SFVv$vXkG&jC-xsZsmNF z^m5EwDa}rFN(8n_600&Mz)aPUVm> zSsso_)OW_>>8>FX;6gNky-rcG@x zoNtDIPTbIzo5pU#Vorsd5i%}cNn1y%;K)wyFl+B={^-rhRGo7+HZA!s`ZuMYI==f^ zMx|dZWyMV5?rP8dHi|hbn>=hxNT5*p;;{$V!X1XHvYN0Z{7t>S23n@~zZx?SQ~`iS zy2Ltmi!)wvKc1>{sx)t}PeN8vPirM8#Ip;tZ%NZ7`me(l5cZfFq z;?ekee|oqX7b(^ja(s)7)8X&0>-=Gt3N+PIoahRi`T`&|3YTrYxPy1D=9)Y$^^3(O z(ALpG>)wjW0BN8r15)$6K;Q>O3-*cH-yLma4&)L150y?pmIqU%KW#peCdA)PR6j9(B(EIK=*8og*{<49@eLta}OHm-mqjgmj& za>*Yp38+GNyKO`p1W~V9yEQGAMEZlvTcd7<Ewf ze-arLHANtJz}TfE;t5fkj>nT^02BQ$3#;n&v)aAjN3p^%27GmM!G5QA6}wIvrTzux z8-jI(sZO7}@RCPpmfP?zFeRq~=pyTPp=QKA`TJ8bihoNfJYg({oSF^ch^_CB#Iz(H+5xn5Jew zQzMnAmn9Sm(}J^2=C0(fl{)lZ=@CW9i^7|vS@aIbLS+acY{8U^OD1=ny6XM=K#5N`?BndsUApo#8E2$oJNpexbOCS z!!?tQx4u!P(UTei{^(qv&n#)0F~bNtcM%LR$WfGX9=}X>b9KG`C<)#{Br+RcRnXy+ zYPb2+%r^(r;Iy^1_g&=}FCs?;EC@9E`kRngQK`H@do}3=3vHgYguVm!t1U6D(Hm;^ zvgev*5+=lAwgzkE<&_fRX)iY8xdvEaHkSUQ{OEZ^B5ir9%o}?BMBcs)Q*$; z;=z?8n^(p)0h$&sl=J(v14Dft44_qqyM`|l80-3dtFSG04D~CU@eF5CFehQvgMqE> z-66(`cJ!-qii+tq-G|)V(%1$k4rMZZP1s}958=ZrK{jDzLoqNh5Zys7mBG2&#}*{`^^6MwTU^!5a*CbDnLc{2Y8duQm(9G=jg)*@KB&_jw(X zV*%WGk53lZYB1DTOBd%}%_%)P6tOm?Au@`Hc>yrJt-dJ{wPc})$Vqf?&?HqS9f=YzyJR-P5mJ=Y8ei` z@kYR_=_38tzD0<|K|y=>vu uS&=|1g;~-)IOtvzU4_V_vW-0!khdge*e>4JGgT{7a+eV{CjT_sxZQHhOzvuVP{O?S1C;4#iIs2@=)}tM+ zASa0ciwpbh+cyNMA7V z4*T|v_?wiNu!?*7d4^j$x@zN4*FuX|E7cKye=Ipq7%4PqE_jbWb~4BLX=?C>D$5yL zD2BKL1X(V*c&>k-*a&go-;{J^dHJKt(kDqafjQ?V@NS>hsjZ_tqQcX~3hjlb`H>^& zTKci~fG_Sp5fLlZzrchlbbD&ZLTRdsvug{ZPd)MC=I`Up7o<^*NPoyn8Q&k|z1)4U z{g9Tnbhuny)uN@Pr5>I#dn+VbuCsy?4-QsYm{-s;89c%CG2)z=zSqDMRXp=eQ14e*5m=Wu3d9I6tla- zpS&3HRn5P-4jCx<`SBIeODZc(Uup}^S8D@|LY-(B=<;eCGfyFxc&fBZ{G-DajZIBh zo%_uzTRtgUT`&GfyE^#I9N3`|eRRtobJ2Tgu~xchG!x~QR} z`1?tG+^Tz|MdLjqr<9cmxM+ik$-2D)Y?--kUp-x)pkGMWPyy*wD(dQW7IT!2PZ!%k zNP@&&<%i{mEv#$(6=1m|e`d0kpuf$ph;wF|Z@U-7>jra1t2XF5&r(Cok}imyCW0JE zpKT<}dx1u~MK0Jobx}hW;{9MQ`Iy95;6NFj1jU0I!~boO0DrO+M5X5)A;UbglSjwCpDA=!k8LMWS!nb_ad}K2JHFbNjtD4>MC& zIb?$1c`n!jJ@VK%U%oW+5{8$z-%oI)ywvrMa zSG?P!PS@D0GqFLE!J5ZpZ`W7A-D;BRzO{Nvliy=)$DUiG!5M@qhOieqYjU}a>Tgn# z>*m!RR6so%o*L6$w9v+2cx~&~@W&@Rb1IBLuT+$^(x0)@jdv$;nyv(1@1YPE_`Q(L z*n8Por`lC1lOU)%(cHnqn{YE&kX!_5)Ss5E6sPaae>NCc>?9Gg&WnZNYsu;3kIT`YFi-fl9|Z2)nmisYB~p$ptqR#}w7!iM%_1Uv9KDy`=>8oH#qaA)q~buHe4jUr1V7(r)>_Rb0I{ z#8cJT&*a`YR!O`I6We_E(M90WbD=3~A`pxFWzhQHr;>-1@hI(NS5Hp3@jQSmnTVCN zJnd?DQl79_U>wiG0)=EPXmOD7Gf`MPKM5JF&{!k}`tWnT);CWP)>&pgN9nt3dvu&9 z7oI#jvNWg)>@=BFs059@xGT3&?a%h=#&ixz`U+I-E)@YZPYHWXDl*;%A$5mlaY3Qn zy;Lt#R?l7phRHqGHWYD`n4uu*Kg}Dq?sN@>jw_SIUKrJ979Uq;}IPz8;%0aJDLkDOa^LtkcnHm(!43wsz zDIX(=1xlr4YuhLmi5jZ!vDn^Z@EOLZSrcH7QHvfv+=K(8&)peP*~GE~wXm-2Doig> z;3^pSIAupflLu$G7QPEtM4&A&x}q=JdywbC)B4iXC@UOIiT~7sn1d8|a%r*${<-DQ zBx!iyfJN1?VP4Hs!&oJsP2GgMRQ&tu} zPcp`IFcQc4VihA%dZ6p`fr-$48)U0PX*Z9Cwo35K4F}#2`3Iav?KazG%bVQjS;i56 zvL1u|&^GpK5zcXD@f}}N(ePlp&B8e?Jj3GeKrI@3;dac1TB${%zqZ-(e+Y&BJ4+zD zZscP613O&2JIj*Fu@P_-amh6g?StdVFg~Yv%8jt)qvhZ&LDtl*k3K3?NtVi0VRT|` zcE5*bw5L8sKBhwR|=Od zfaN^U+(80`3BW;G@6*2OjA=_5w4A3sPAe@^kIT%I;%%im^)?I!=8bdj=$eo!q_^&r z*pUW;?w(7&c*#ig(hP&JOoH%$JQeQ0mQwh#vv*zrc*}qQoL{nd*gu=t!s>WN8EjoK zRyDo)dy|yajEOgkcdJB=nsdu&{OP1>$Gy_Zo{h~ah}1`;mrx7TYZ(xXp^}KJy3H{z3wzg_eAfu0xkx@`)F5g0WiNGBpfsr`W_p~{}BzfmOq(nN; z&r2GeqxnlPzC`=pGtFrfpPidx+%@)t!Zlirccv74H;UF6C!G+dOeVi);nqryx%4?MdJsyx%xBayP-`T+VFC{MaTE$z&D)~+gS7PFwM^N^ZljM2(ltIch)gCH+ORP zvgZaE6(K9uhnsDm{ej|J#L}#k6@ervzjPK?hOeU~5@3NQe6$v1>dR|U(6iFXkd01! zcpqYIAHJ+b@=qTR7KBlDagIT82%&>aDp~=GpsA~WGU9BM$6=Lc1!(tZd1%KTt80wX ztWAEJ-7~OM1V$YA75r__OhB#v!Jxwy@N`ZaT(jnEb-R+&)0+#GC4ruwU;OM5p5!7- zyJ5Z>_rwZP+D*+wfgfSF7Y;-$5Xl}q+$jU<&}mw>VL@n9stENMy{tgAJfz$lA;Yl2 zIcf>DM7{PPVd2bz(ZxQ0Hhd24og=Lt_TCaAmtNTlZ7u&f%Z^>E1~MP-N0h=GnUuU~ zy&tooUQ~ny9Bi@M4{Gq|wSgM=QRZu*Guq)Y7Zj|*U6qLyD9Oomp7^3n&r;RNnXtGx zR905jYxh)AkVsF20*nRhsKGkDp_FGo8DiU}v~8!XBVyr(s&YLW6C^rd@_D4b+6R}@&R1M z5SN|QNi;sBinM`VG3xlGMOspYM!yj$F81e>yl~m!HZMSZQ&h(z3~(V*x7G^mM+2UZc9(FSC+> z$Nu@5r{X~Ny^HLxosbXKP@{)4tHyiu6o=+?pf z-2{^*-yr1kZ z@i2+vf;c2KJJNumQ_ih&g_W|VCwqc60@k^LcPdVYjyDP%EAj>(`ke^{MRT1p!i z7x&&z=O4aTX?Rk5a8#ef=I{wW*ahbO+)I{^;VWaQ5udKDb#?gCaPaQEO75`{jH0vN zGc2A0DW}r%e0*f7cJS&HVSxR&(9A3+!$_5}&`&FIOU+E>t0T0(#u_PB zzf3AA_8TgM{V_YXY-h@jyc?GA?^l6~0!B=8d0nip#n0%z%WysYNqwe2JMkF}^y~Ud zrM}>Lv2~jyH9OB9+0Mj_jFl5c8@60?Me<18jNi~GWx1KoZqlB5C40x3Mvl*ebkn-{Ge~{iw z|M!h!C1&b7RWkS}ybyDe?mSC5oU~hSe=gQJyZn!;WQ~on;!eSLew3~tjTgJ*kxjZ=Dg zxmrvR^)iF|uCaPtzB&4u3rE5(HB6Yz;Fhadr41e&9@g4!wEFMiHv9=C^4M=L z|8FT#hijP*6rupT~Mdgm$she{C~i4Ln2Vp?Ed~ z&O>u(%W1AC8W`<`ht%CNe1o50y?*_T?l?wp&RAcU*F9J%vZl!gEwrIImLRCe?;%b~ z6KiQ|XQ9nr2H#%a2`UwG<^_csE>*Ojcr#+nzuEn2gz1X8>flL!N`Q)ic_o>{61uOW zsH3xfik&<*An>$~cE1h);)WHmb-j0W)UdUS!sFx#_(k<^peC414!}13bomJ@bhPGv z5(>Me&finKJ3@zwoq%%4B_B1>SE>VNg}BtD`I`rgH*wpHWYu$Yutu6nApZV8p7GXg zoHL8?vumpKYlGwI`2LGL3c5ITc2f7#uFiY(dn*0T^P zVL7ES8#zt8uy|5@>G`gX#>vsqo;QQR_I4tTtIp%@(0|V|F%C=L^Ps()3|osU{R>f1 zO)aD{2l?8x>BGi>#YgF(or5J<-M4tVrQtxZ?&7a3*w#DGSPVB}GM~GnDvi32`yVbY zwM-6&Zy<-tI9G+%(KiC5?xwP&D6MsGJe|wRaNqOwq>7fO;4V9F@T!2(nR2)q5UBP?W&i3CJ8ylx5yMXukQ9#j* z@JW={AvbA_0C4o($(Uael41@MU1331=y|T&{L@hpUOM=Dkh1YWj;9(?3`f3cCX(8?q45Syz-%eeocnYfUAD940C$1W32Y&b|5%GURx@+9!7e^ zJRdoL#-E=D*)MfJE{9=@hJ+@>i!pnHRj63KJ4s(^L)tXO)IBSk?D_f!yz-Ke zAJug)9Fp**vHz(_jiUOqiXf$sqwM7!mvLKWju|G$sey=w=IdqXpmScfOl)F zNN7~1s@-$)$rfg`D9iWtME?QtOIU**Q?2s@+K2tczv=S4HptYJo~egy^uIAkw-K-nOnoLTUIX$E=WRH%h>+rM+x$em|5mZ zFK{2F`*XU+Hyi735z6}^f{NJeu(WvmBm*K%)N?#?GF|LoA9MErhP|oi*rah#ZMx1j zT|#P9dkHQKLnZ%R)=bKmUiGxlkUF@AdwX|RQc+Q$-{t!|G!!6ynoYI@XjF3j7l``` z1hdK-jfM+VN*o0|pJmQ}^&c-u+bx@}t_Gk^-GN@zI%tvNCj%K18D_QzLl=K|z~ZEu z!Zfs_!(1Rw9`TjnvG@ws{Uk}h-jx5(3lrm}j|Gl_UJcKyFdL1`Emjla0A{$gBk2uyyoq;hepI4XBh z3udN9E0Ng0y@O_I>AFs`I*}DVKK$W;q2&0&PO+bit|NfpH1$>=Wza{jt_rT@+u^0C ztCHE9js8??LM!UJ7KnH5#}0g>2H>U6LPfZL=dx}@qo&|nSCe|3yPv@XlkQ($jRQ=i zst=8xdSRBM0Sjs=)KDZM)1E+x_vgJB;k}A)pWbga@VM;9>vqeK@9JS1NvV#9g8b1D zKL@D61N`i&Oh-W2h<-|$sbHZI*;XCiBo-uS2X@&Pe4F_->Yu8LThI-NP9CnZq@i@_ z#|yCf_Ijb%2vw2tj|Ew-{2AO03{$R?t+I)##+q^hc+p(bBob(|Tg>EaktR@Spa@I= z!w^sm6+sSzQ=VZ_6U~=9NuK-VAPt~7(#7M3so!S_<-FE62N}cNjox%V%J;sSA>yWP z(^{G>2Xe4y>pHV6kwIOx4q(}$o~&h^`df$nrA`A^dQw%iOgm*%wg&diOU|tTZwVA= zcsDWz#Vi^o+e&)wEboYOUgu=S&6DW)Bl?gpQRM9M+XEz%5}%_0I;e+}JU&g&lw4ZfjPo^9^0!sZG9R}AR4zjt zBEGRVd(QE^Un(v>-mk$cJ$y?b!25C3Iqoj$mD3Htto`;JfIbM6E;JxlX$K~GF-0TT zgEvCBHuYy=p(~j>+^r`{bt25+>JWyvVPQ6yvtAm6Tnt!`~RngZQNzw2d?=_;6_V`-eHX_v598K-}oawKMmN67ND%2>~Orw2qFY4lu z{?^&b5QNC02eo9E z2vt%&_|E+oe8`XWz|0ew=<364Kg?e-#%NVKbK!C|kbfz}MuLVe`cE3kh|}xDk7eAc!~EcI!eR7AnxPZ$+%1K(+VCN)_+3cF`C zRzkJMk)A9shVE?qh-~ywwvvAt$cTxk>q_herkD)GVya>JgX%K=LpmiF5g;4f5M}Jv zDBe_Pm8R|iq%Tc~37Y$JO7TYaa$&#RxtYTDoqmhSN{OU<)#&9#*^6;wiK*#g7KZK?wKPdLTAN$hR1O)4z(Ec$#1I%{`yw-Q2NdrsZ$Ed}Z zFrZq6b}^6u)D@64`Gq(E)dKMmeP!9c9YisN$!_HPR$$XJa2b4EwEdS!C-J#QeR!*C zN?Yb(q?~nJtuKaF4$&K=0w&bMnxw5+aG4oQ*- z`jVPLZ{zyh`G2N8wBfT&mER0n`?xCeVv*OM8(8;`osDT?lMj(eSHWLr9wqQJ+jI)C zm<(BY7>Tgn6gEOpZN7^8wuw6P4q0L^&J0&aOXxpHHBsNy*^{7MdWDZ860C7-y>wrt zem50*LKdJ+0zmjW0f%>O9cMnoNgU#@ar}($^(6KGj2*&cKe=OY)3AyCLIa6Kbwngd zJ$0jbJGfHkZK?bAzMHQ)*V5nZgc8+SudrTrJn5-b=^=El*>w>xXYHGJD?6Yr)!4AV z*G9+Xf(^5>bBjxKy7ea4{nyF~Tk9WW+rcPYFW*a<&1Jy+`Jg17o=%LbB>q!53%Z`s z5){j}Pv}r_HcM;-W4O3ft_Ly~wZ*8x?OJa$f{cy{M20}02NFddU1H|!hMDJ2@6g28 zG2d-r_Pe7e@Kd~y^uKg^xu7hsf3N~f0uV#aX=>j_Zgh9+$JvkFdIAgobPMU2D!?v^{p-l=^p_8>y90cS#1gJ!0zjmbvqlx|Xxb zw&HSl_NUR>$OX%T!Zcf0);51qdQ=<;S|^+bj3NbE2st%ApB+NZrtxA%i7x3=v)mq< z+s&j?%tT+s$0W$s;uIITA~gdSX<;i}f)eN26JxMG-rp#N2p@9FWDE2H27{MLJ{>Q2LAqyj)NZ}Evr6LFw7;7=b zjEIF$hWnojY*xw`P;zO;lCGS$x6RXyuE8Qw(xCy^P;z3)0{G$@2EDNhmK2nfkVS0u z_<{!A-(1g^QEuCp6(W3&NdNdgbE#<)P?dEo77sSpIBfKJ*lXaUki2sNsx~YR?<~Gn zV)rdy?R!|o>gliZP^uuzN;H3{kO4=huVc(30mXy<-2_08>%sp0&zIYDXTSx6gf7oq z6|@N{>~OF%R=7$?lj_$Me{@=5*J~LMqMsYS@m1l%JzNv(K}pOscIy5w;fkZ9^!WF; z_$lw9Pkw63@1~V?5#GtlQ)fbI*N=s?^|TNcv6hEi@yRl$8|10;!f<%h7}83tZwC0> zIJ!?`3fO^?U9{-1&b$P5rW3m(R9X4;^$B25h|f_pG&Cd>6v4h9uOQXNBdGj@NH8#Z zGjcgIB;mH`iABX#G?b&+hT546>X%361@Qw=jE$!wAHiAt1700UCD=|(Ei$RBH8@`TGMhaNn_7Ca zJ)X7nTJ0e0XeCjC`+z%XUP6xQ!OfpCf6UmMf?x(AAen%ZEi z(?_F1Ejsi530wc~^nG9AzYYHTpDgO$_JPTM#or6i-QQBtH&g$O5Aj*DWK`OMZvHv{ zPaL^_qjG-;g>}VREw1(ameQPG`5U1XQMU<&`u?+U5nzQZhW*f|r>D(Voo~aVqq$Z~ zmHh()H!EgYHEvgWgHd=#ZW9}BTN58oTT{&rd(Ah4crWL5Q>hsk3RKP#Sqo4V5}^we zFS($&zg(n1HY(By!-v!oLe8l%;3E+Kl{CEA%~}NI!kDZl1?UF55^5`sayZG?@HP?3 z^NCuIyP_0H9(GtMv&U_>&;5CEtlO z^B*ES0dK-eotd(#syMJFBNGz{$E<6|;CErHF^qJ-=A`HVKLVhhck*N8a^~d*6PFEj{dJr;~AUB_rT*UT=C` zIouyBe!ebsy`B(tcs(5g%FlJ1M3Tv-#}PpilYaErL2h>UR(~nGM2_@HG!1EhbOfLI z)!!+%rCn=Gu-l!+Q#G%IbeJY;sC^e>F^lGQtK+D(FhE8D$kJXC(=AQ0jo0t{OH#Z& zA>M(CJGih}I?+G9-=@6v<@DfO0z*q3pY0DbghltJAiD5CW68tUUG(D|54QfXJ)yZ? ztPYGZb&VJPOv7e2_~!HW_z+GRWnN$3-co~FC%PY86YlL|1)1!8U3=ykI$S=X3J9yr zHh+`700Sb^D`XJ!Cyed?vHk}4+=8Z>x&AymSd^TlIXyAMDS#$qLaTev^g;lhCGubtrG zElz{zX5PrHvN3KMrF$Txf?k|!< zEVP9uH^Zblb&ujej;(r5U!9`_OaG!wscy_g0p=l=aBk^nUd!21^JnXM89 z+bJyJ)N9xf&iS(=dvr3fS_X6VH^r9dF1w@R8myLBjfas( zM@PB6pP9)dBEMa0{;oxHUZ1A=1KklPSmH_8%06jU+t5PZImY5NhxPJqUmhS=gUdJy z+qaYSY+!|9_;+4J7}?!e3_tLjWK3`+;pcH)4Ctm-U6dL|#6T}y6}#%jwLAa$a!t@= z1|O7;kn6byq33aq{~l}xint0ZZ$)^%JqHrf6P07FBdREm@-*M)0-?sIjs?0r{Ky|MbWy$yz$l9DG3d7Dd`qlOVKa-C=Ts|E zNk~YrKdWeZ)#Y=)Hb`RBJzesjwQRT@z|v>lyZYKrqT1SVuSjMScB-(<`7Yp35K`T7IR3X*SC+W}eu{k;{1f5#> zx9yrC!oCAXhYA14Zz%bIePtIBp;5mz9-&TA16aumMKI(*m_sNzS-}Xc<+2wV&>&M< zY7-2w<8UNAm5!@)<>U}K)1n;q1|8nr(TYl{s){NrMKbNw1z!$gLQ#RF@R=uQu=} z?qc08*GFaxWI+DSk07vXidr+;35Lp1T+bj_jO(b54iH2F+cXvsd2UvpjZN(;22bPM z-*3U?7MeA@>H{*pEK^pOx^Rq5^Z$e;OzZwttJIM)G$du}d?tO`^6R>CPiEA8r~P-e z-V&eX_qp=aL@p&JE?#51!E4+3Vmdk&gcUm{PKAO-)F&XSyUsx#GLI}y2<)wBz&GMC zL3G7h(N;;v0|N)55)rJTLn0i8Kv5v+;SO0HA zN;);F8Y#f}PL3o=qk|apJ>F~-UD;n`#5CHV^enn8s(+3?``(xtYrEBL<{UJL>zye) z)?OVilwo}ndcO{`v)(g3&p=()z5+~wAFS3b=8e*w|QnLGNX^ zci9fZ!|@c~U>v}qa{qie^0*nm5?#IB+ui;5v~pzbrzvfzN#TV zJry&Ax2$^1@c391Far?hSsFDwc93(RrJ0~Pd#wHJ&-<5cSC3IZ7eTaIEC=Z}V74D3a6`tx7#L4s z6GfFY^4fonWHfKnk+pVgQkyFUVgvuFXMkS-=$GTE38PR;1-FZ0cDNTdV7Wo4l0nM* z4@7j!y2fU1u^U*&?zyW2wfI%RGRVLE=Qj@lT(W4pYu=v)Ie?6Y`K~1ug0qzf&dshZ z(l|1iij)PX`7M{@of5`)r)|pd0Ai*%zRu@m2!J7`OO?8S(D~Lr1BXe!{gC`McaKj@3)rSu}3U3+ARkij<(6 zt)yc&at^c<(OdQq?PxyF&#gCoo^-Rgn+*qG^+67Sna^UiNDm+#Lgc{Nu>5>-LZ5rZ zXndYtVC@k6c}wU9$1|xDa#Fqq_Yl^fH9MOM`YeKiq-my^CZYn9K3oBS-n8Y*2N?tc%(0SqJrj)z^kH*KJ)hRHBq~X&zk~%l zv33#RT&2%<*_1CFWUVy*m6MEy+@hJPwBUfr6>gL$*R=~T=Y$j2hl^}F8+MfG6%Ayq z!1Tscj4nkS99RIC@jJRWFfyd|^aufpo9u^Yloxw{@BI33HZ;MtHD0Wk2f7=P@Jq2c zt`>%^U%?KB-K}!G;^<_-M6m0JmyBcuAMWyHwo`csSC!NaTsRVD(PG#wBvQQ4WS&*} ze^HqkNQ?|44)_UJIGp4Ke04o!V7QeAg`B{-Yj-zbAU26v=7)3$dCR^~s6%qcYxmhj zf4}z>_;U&C=3$-W%an5;L>ciCy~gDg+ZgVpZm#$g7%BNsyQ7XX+DDf z?YLNdydi)<8X=jm;y5~bk8;yVRJ3?_1Ls>-=LLtD9&Vozcg{vH;wpo|9rQH5-0VO$ z#eWxhb%kf!-1Bs`ysYtGtVJRkKU}NAbT(h=_`%b*{YIjm7vB)Y&je7#Kc4u6_sqIlK;4iMy)XnVkj68g!1&{&ERz*W#}1; z284K)^vhdI1-MSnrUuv8Wo8UCPtF0kL`{D9vuSd_rImrdn=5Q+Zt0J_{UO@}IZNf5 zL26|t@6R{DCo`LlV{h?PsEtM9upKW|5yg=^tl2avDkyYI68ZGgRkimX&*WK{n|GVm zkw_^;u-0YI28!%R;sbKwP0Yb3j5N%}k64Ijo~^AWmp4 z0N%>4emrMSsnG8PCxyO>AVXRrT^f9+;~?bnKJlVFp~c0}7sl`*Ti{SNE7kz{GuABZ z(UEa>RJX*%r&h5%cjXI3B*+yFMeH9MLL7cI}{&6hkPdH?@#8`KeqDS)*t1qdQ1xy{L%ChYmjDmaKJ|tNi!0VUdwyRZIVQ*gygF0W+bb z^p@75X~PxIR6Ab$q%FOhxC4v=Q6dW^*0YeE;}KN(JIk>GvN%#^s^Pw=>EiplccEOy zC;&RNDG;UNip$FG1b|2VaDr1yZ^VqvoFeN>=yK&Fu2!KnkPQMBcFLAIjzib-oUzCM z=HsET`)&0=(a*@JKtDuZ`gg1N6{kCwpUiP`so6?a-M@9Z+6j|n)?9W$zwrPiDBObW zw-2p9P*yN2JFcAGud|xsub)|HVG?;Hyu7Kv?vjqUU3r>-Du!)RynWH9eqC~xO@zYX zwkIA-W-1SLGU;x!V+ z1LomYq7!8j&1JB$x|=^w99#bJd$1Duy|VxV!}f+Zv`<)76(g70kR4aCL) ztpzV^x%2I8GzaCc*qlo&#@jbzXwTcNDnMdwNt4s<+<2q!Nv6yE$>r+^eD?Vvfjr#K zRA{IZt?0m9_`CB;@%lRrDC>Vu?As_a6~(SZl3nHi+m?wTN(Rso_s-T>aR8Jnr#ZKD zFV;X;Tp_f)RIabJmaAaWt*IWle@%P(^?oFT!(s@Ytm~>deFNL_W5bQ`sN2<6XX` z`ws}8dN=3pHfg2F;B@8FVF_W=DZeWKBczD~%)M{DYm8-%X`*`_Z*Hn}O}$+z%HxbG z9d^^~(;Puof+_Tm9KQ4GjE1!-lCo3e?Eivztb zOE5=)nwp78GDjhM#@xPbqgiM3XL@q-(BVYdf8lxn50PiNx|)5rAnt@+>3 zY-G$MdRL&6I}k@s5ki|k9@oGo)z#FL6cqf4p`io2GX=bc$Ht6+L||C%kE6*97$hXg zIC8lR-hluxsN(W+avGX&K(LJlz(86AQzv$?NWj{K>BVXTI{xYy2Fk&^O?J|ZCeA-+ zSRk7HTIeZr{_f1m+`2&4vkPWwi-&BE>Eoaa>}TwSf#t)e#nqwxa8(m;^c>rUAT_7- za#vPAHwHKO@SVa=MQ;FF0G?A~OA=XlRo!NEZnxPwj^nyL5mu z2V*&7c(sIpFfz5?8)F7j^Y5L$(7VsT1s#48%nFH!A%<8fNInMJ$eGc(z78QR+2yJy z^IY9WQn#l?mC6c$i6cQ8#bIjpvCb)!>)hVF{> zowP3EJ^p~`eqQWkdR0bL(xVsCPx5$c(Giw56wKr3(*B>$ zrK=$LF!+TGL%vXCsFR|@AN%a0;7ZZi6v45PVn978wkv;kU zmGrsw*REMEwc|y@(rkf~nJfKUsIVW5CUA>tww3s59zI5Ig-TCP8sM%i$Bw z<+=2HGTFVVv4QI1?e3$6RwNkp==^+4P*Q;_d}v2!z)=T@|>fXF>>XTT>joI|7yddU{VD*{%W|#3(&s;}H~=&056pslfjE z*2Zb`od~fRp7c7jlcpeL1!$CX4-j|raChe?<4bG)isNqOD6?s(>hC$2Vmut0($5(h zq0lI$J((858F(@OyMzc${ry6o80gXC|5(6^4$;FcC=-g%nw8twQ)1G-@Q693#sJUk z%IzHJP{gF9fhB!RVy~a#mVdzJB*qwQO)KdUu66g5vMyP2RdWBxnywcFffU#OA@4WK zRS>&fzIFU;tqwaGlg579kt(hD98ob1?Z0si)12_?X!_k$WzmvA*Bw0a6JrB}GsF6O zl1brx`0mCC&2I~I-`%Gc;vQmq?<1s&Xg;RY@&(HQ(>fG1v>=JO#~(6V4~MwDf!C)% z3cVjkRRfru+Kh zREI|>MaDV8=en=*<*b{mdUlru9Pt^&pwnn~XOT%}G?@|#Rl0!BYa8k%Thp9W5lue3TK!yC{MH_N-v? zP;W_Wj^N^o<@)CLqyJA>7%?SfNNH(lo#Rnju94^=mK)E;+#3)d=Vzmgy$siqfaWyD z8I_+WZ7A~I_6StU6Lm-pnxCI%_PjUev{?o3p4mV^Cw#yHlaPx-B1ZHI8aDAMB!LFa zrLHx7u>ABMBB0l8MUPVY4l9h0AQy{kgDWriLJlBuLm)15f3=kr1ch{4^|V>^dGw;t z4EHUVCF#XZV5t3wNFs4QI6^WqSKIT90nHUs@l;e88NAETE2sL>Ty$C?`%r-<*gwCi zMQG_6R7#n2zMY38r9=EkPxz*|5Nhx1{YTl}WEz7?-pt>G1ThZ}9^e3lud0AnkVuJb zd?@#1@$M(0<-F}M_CJ3?oiiIv%CWE5%#|nw3+L=vgBlI@qYSs^>t48-vj=u|cKi2d z2SH!nn6<1)@(P*jc?IA;E5#)QKbFwk@i{x+Z)I$|_89eh*pjK8o|c07-ArG6lKasfAV(DM2Uko0FdN;2`c|Te`;c@EHseL3PogHaabkV zp}2NK$&u{J|0J?NQ>l!8m<3Be?*=(pR`(qlJU1_|q^yh#hztKrQ;Q>CWYF(_V5wjl z(9@Ck%nfKBZyf13LW`r`t8H^&Z!YF_0d4*G;p539`1x#fd;4w$8u5aw*LeZn5faK` zFUzj`mNJc(xQr+EXj9y$I~~E5TD zmW)Q{Kz-a3h?3pQurXiPC*E0$YNV10pOLzq;WD1jRSh`UQ2uT7E#SaK;LV7Bef0#I zj=G>-v;|k>QM`EBNIT^~RqJy~@pzSJg)&NpqiYV_1c?-DqZZU5EuBjPBkpMiyT*Dk z#B_;y&G%I4JmYH)_3uZ5I-K`PmR28d@H!g;flanJkwgDR0y|9bbyP>Dh*Wp&TZg4( z4tvit_c7Cr&)&J79anHWR~J=A)KH$egeT_%rmmI!|ytE>D zZBOm#3@R8!)YT*Lw?KsRL>0~yEa9o)71v*zPTrljxrzJ^D!}uUO0WgJxkW?Ze_e0) zIG@gkSHF5&zjY2|cHx;>FxIXGd@F_^`OaMBR^NrQV*{4=@k$TtZetBAY@qW5eQ0gP zYBkoqM<=c6?qxcxws9d290i(*f3t7VVK|+zA^kf$tE9jDd&Iccz`UjOw_a6IV%w@ZDk@os0ZC0%UcEEO<7o2glel187wTtLRGpsLVbqq}|)4vEW!{Bz5Y zpvqmXwf-+78?~D(NEkwkV!o|CczIs>2dA(K@(4+pJSvMO!9VxApT7OTiKH=L)|_PI z7FF(|tEBIqLZ{qxpqszq6*pSFJT30MPra@E4JbHkgdFeK$717piXf$62pYG_$}24V zBc-k<(W)R%&Hi>LH zcPwzK7L!qD7!Wc$a#+56|5CdN5NcCk#6h`*#pFeu~=so&u0d&cAmQCm6J2JX6QEYfELHWW3>c~q$ zQm-MMxQSfC_x#B*lH9&TF)@p<=$SkP*x%x(-b@=NPxkxv1VgX{!{1}LzuIkm(qjwM z1Z196XN4xZO){e3Cz=0lhA6;lCh@49?EeT3Qs%IYR_Cc{GeJyPPV+?CbViF2yk)i% z`a%-ati{B!BLPd3u~d{#n z&>&z50nRAGsp8Cy4ZU)J^AjXGj-IUS{FpeNUOf_3i-}=wh}#7^9rdV>w?x5qLhL+Ocem2)S+*Quzgq7V@g zu}3KuD3Oe@62=sX%YiY!pPs$gFG@>s<{01fRS@5KrZgB8?R+k&(Y+#!|p&Iy+oF ztr{of$f2 z!Pc6>LKZ;ftcxG~G=@zCZIB4pDieX;t>*9SN-q#fsqx5m1I-WdN*qP}h!2;&_p4b@ zL-OE|V{E&WlTGm{dG{cBj9&{u+wdG56pU}FM$(S~8t32m_`b^xhERJQ!D6bp zBHgjdb^bwp!AQB3lxzi(;(0v}wIpC|Lnov|cjAj#zL=b@2q?u<8ovBWd5_pV3{3xh zpCk@MRdGbe5Ee#fp+9Uc$7U|~7;sV5=}T2}5C#|fu85fs2^t6v1I7m5w~yaiWVG-U zQy5`E8F=;f*74->Ffje0@-V0Bl6my|EqzYq8{6JEebyWXjfR)7l=0D?LPz4**EyOXl9kx*>*zNTCO$q{vy5#0p6i1wg zRBi3;83RKV>ZYfVWd&?}pZ~~AZ3P(w#jX5;{b7At94nE_CGzI>%BD9fHpeznfG`4X z)c?_R6+l^SUHhs?cZ+nFAV_z2cL>rT-69Amf|AmWG=ijbgCIyshlC&{jf8al>-}c_ zJLAkXsB`vSd#$Iogkxl8my9TdaGG1gKdX}umT5{>Kc-kuh~6^&_t7Ng)R+s|m{sVT zV9wR$2j9I{CnhJvS8|0EIC=QpHX+h?Ey`2gXFrL#o$*&H=t7Ekm(0ijE=_XQlS7Zp zbUFqxp`W}~T^k#e6?ANR)BiGj*|_xQC3gzOQ702uF3*+8hR7u>)#W@H3D^b07&$1G z9A7_SC^$b9hT8bxi4C)im|;?fnY@!Hu6>cTr#`J-CZngXxP{l9iuPM9s#_m(-3bQG zfqgc)Cl(3Bl6kTt8+)qAdYoTdd;Ni2=nWSAI^kYI@Vt1-vM=s8TMAw6+wc%)lt!5$_qgR|A(f9HBKn93`4P@0bcl z71uwt@Svz?zxlJpC~xw_&_=rQ;|*6pmjuP}y}y6bh;z5XU!PqEY;A8RO5HWBNY-Eu zRx0SUudUl+OQH{hsx@fiG2y&)dinYDX9y`^4f^9XeX!?sPhna&Hsiqu3t|e+!rU(( zGWB_O%O|c*`^xYM*#^kYHVdVSx1~M%s>bRoFyb4nCrjGC%RdiG4oBzoI+nak^FZ;g zX3W9Mw-eJS2PoF|tubVIxw(uo1tjc78(FBtg_QDHgdDB6_uSh8lMmGWKiBAg+58rg z@3LbnUx62k<*jAgBC}K<$YkK#(k)nvY?y?n!tqqvg)yKPvpD*1w*4i(CqvH{(!uO{ zYO*p^MiToxtWo?3y9nv{St?yA#yENc^blO6I~CIdX}k_+2R&3k$2=48+`xq%g!ftC zwb!=C{uEx3z}u(VorzEWTCBUs8&fQj4kW+oubozvp4gHMJyD?)_AW)cZhz#ds%+D< z9Vk`I@zpp(`epa?pfUq&tT(tlD@^V)y^2@+(U%IO0T|Q6ex-(|ZY6vQ%!HkPPqmGW zBTOrLEGlbAr}uqZAvS>=`#m=!DW(=s2YeSiWDv_@5O8WI#J3tBLqv?tLhoiKjeYQu zoZkESmS&^I&b(1q*t{?DiQ8Chef130?&srJ|NOKoDIDv`JNdYwv<6YE8GJ;!a#2bQ zzfbQU_%hHdewwAz+)mm@p~gK?T2B6EZ+I(1dRtL(eiad&VlUizL02ns~j@IBvR z;Y@7)_DY<^pfbixmg6astQ_CZum^naf4^)_CrPYV;&%A=Ivh zhIA*C@nO}_yJAbu3B_L;sXLm2M7Bd2IiPRUjNAbvwF;!4f7)(Z`g#?xc(2ZOrz4wg zro4ZM)6u=%+1Viud_j%-)r#8$xA5;4nq}ifzj8`|BJ!It@*wNR24#<;A~qMz-3ykV z>F*cM;vOwl{5dT79hn9bk(uyOF_hjBYR29Dr0A5@Gq zU{z<7aV&+sg3nMf^pjWwv_1^wcdxcIeB#7YkPNGJP`9kKYuNlWXrs$nF*p2y3Zs_; zGh16a1JC!x$VlTek)#xlj$sXjKNFvQ4~HjKo}+3^<4Vzm7u9Bi3aBKviZ66E-tDr( z>-t;9Y-RjNol9exUbki5@`FtCHP^~y!(`9jS;p=P+f&ioSr;+M3)d-Ttr4Zcp7uxB zxU2(=L!}JdCLfKm9a`EHyKxn5X}r(M8ZOj7xu3EgE@r$FBcxU=ljISUutncK5_*!m z5NYL^qqOxd=I4DA3tKCe&<*Z=UiL(jlKV~3^Ed~90N;VYw$ z&T34~s?7eqDn21;^*7d88X*hcIa^Utky%&6=d#-_j021FS7P=K4#t@O$$6)LKZsTM zx?kVgzJK|RU}K{D4KK$|l88q`!q~h$zEE?hYGuyovy5TD&-BWB^Ne3S1nToI)v%~h z-*>0ApPoz1jXyroG%90$$oH5?j1lirpHu1^a-d!)pkezK^sS)BM$^*yjp=Un3%Z-) zm+aT$UaRYVMdM+mpF;xrd{2^4cg{}P8seVd#WfukHve4%V}MgNM#+Cyo-c%mKaxqh zFxYfG&A3;nb-7J;CEO;#i6T*UClPtVNT!z9(BZ!*Y_3MY?`Sr(eesGOG3mIGHMWr_ zPKAnnqAN}zL^9zaK)|h$k(l=OL*3jrmy5UD?yJ4t3wH!ue>)*E?$k6i zkXLl(b$jm3uJ%n91LfOMZ{pWMo$27-4U7}xMGgD=~G-MeBRVHUNwG&BI{_Y)P5&H-NX-z(c z?wPY8y)I9?pw*kY>rNzkDap|N^0c>bj@eXe>gtA2qo$~gN){^+3`kIeUJosq;1P?Y zm%BJul!#7<`~aTJo35d9@vgF&#*&0HB)aPh9(Cg(Va@K$XKb5`lJsKZicixhD)Am_ zqAP~7;(4$+FDK!OUr;K&U=OK2UlwXjQ^c7c+!=6Qa|!g1N}euVYW~}{vVJ^3Iwlwu znJj9(LKNKT<(SX?-_@SvFE)$k#9e_{i)wA_4grO>z1WPRY1*PeNoL+ z7`c4$pLU_zn)-{uj_1{Jfo4oYt->3bt1@N$v>TDAzE4==2{dh`rqXbEgo2MQ!pVib zBiFM6+xngkxtRQ-#H12y(Yk(P?|Nhe`c;9y3@#oX;X9FMUtpqfAx9-pmaQDif4TMNgB!^V5D|~3-dyt6h zUGJT7L4UJlfi9NS6RC3#r?n>Yq0OR{tRzSK%@_PAUObO;mIcF@t_{iNhV8OMpI7UV zqp|UYc!2}0r8EBs0$Uv(pP!#=EwSfK5EB02A6On|;bUmy%sbbeQF^Q7P3)8A6 zlm8ibwzZhR8G!oiImI=T6-^ORcoiG7h@RxMIZKKoiAzR3k@aFjWsG@pPmU<)SFBUB z#e?NuxY>WCAISf8h)r}kwJdf<@oq4OKB_q@gYyra?kX+mj%RBi%S#7S+o8O_Rn3fD zE2oPc)#~C=^BSr}#iV^E9XR5SdCYgJLV7ma^ZftTkr7= zi~kFVLd4Ej3EF@&jObrbQBtC1V~eP&;tsgIJ|*sP`uXJz=-Fy7TaJ&9*^O#KA$N`O zQTf9>{R-1Z-V;JpFJHdQFQ}d8;SBC&94K zEN}kM^^qc-^U_a04?K~?URDaj7uV_G_Z}9_9&#emdvH7i^++t{lCnretWa}ixmTN% zu1xuv92mA<;UBFJ+xC3$AoKxc-=8#xhT|z?G~~A+0Ol_>tp1a$lZDZpE%`RLX}=C- za&l7OVIwG4p{U44`8p!*m;*T>U&-o2=x{_2A@)t?tFhEUCb-JKKUaxT{q z)@XeuKXB9|Y4vtLO+8#z`J-YZJ|VJ(JXCDZVHN{e*4;O+b1h_dP-=~$Oe^%~8(?;V zj*`KL8TGDSNg}|JGMYNUg>B^@t~mz_9OBZN+;O(5aqKm{?{`RqMwW*;nfBI=kX@V1 zp)-}JF2z{mc6L?}O>XcCO$3E1>Cm9l)*YO#T%WUzF^PVtJStdi4}9qR49nDz(Q9hk zr~i=ocGF)bp5SBky#dp#uNNW&5BaYZlJ`WpNOzEA@3AJoW4FcP|B+gP`hH-|V&P-` z6L(JmVmEj~+J-YV<&(F>Lf$*QaSXd9L8eAV{o=Rh>NbNZlAydy6@I}%6>w%=(gO+; za7v99zlMemEa;6OpfOhYRbElSBq*4QP^moi+pT3ctjc$~gC`?X9q%0In^m#!GShr^ z@iV8$l>JzOhKb1|KM~4ExxCJ=QJwk4zaZ!;#7}Kvhx#YFJwQ2 z#Pl~<*&MwF9V%MC(?!>qq~@bZN!B?ocEr#~pPfamH*99!e`M2FZ0fTVVr%4HjUMz` zsX(e^lJ$qlyfeR87LFwD3mI~rTcSg7!oG79@v6D0P1u&bdZD-E?_3K|X9bCIo>T0W^s8l=n9ejds- z`-OC;NQF=4Em4P+ymgo)kC2981}ZXJT*sTbTV7HMu8F?};TsB_uA4kMiY6Uq1?JoM z6NyYCcE@%Q^ho z0Vl)sv%uC#E++NN)i&6;`;Xr+S9z?fUHsep_IjYgo@*0F;&|}Ma81c>AvJ0d@aMbR z-pwHM)ClfbIrx2gDd@YeZ?EsKU?eAk+)RvyEBj_E&X-;>w>^v5E$#B%xhjuq7FVV2OLnRy zuBz>@Qw=L8%ZfXD*vBHVGlGkMckF~c3v&ceOdMHr=3DJhX}5l$`Vv$vgwJnsVUwf7@+A+d3a` zxvLPDKe1qsZD?p1Ny-%zM!+-%uAE3YIuO;8B&4F6e>#RZ$W%cOn{*Xt#W;lQ7x?{d zD{i;tE;QK^JFGVnuMMkhcrRxVI@mAf-VTF&oYee1x=wEiRONPt^fEpsYqf| zvAc@i!^~xEg-m--il&u{3OUq^;qQ9%fC`P8$rZ6l_s>Px@z8bI&?bIl^jU2W%|yRR zUtbwI|6|K3mQE4$CcG?)~^G z>R)0ZkCcSMCv-D=+;QI~A(y zg4~LxX)DJwgZEDlsTJ*@^flsn552bgLL25g_~7k6%3Zq}p?O{FBBx5!Iv=w6V}(27 zUe27yrs8_<<0Y6C);9Oii&Wdu`_?5*5~8X(NJjCZ9o@J&)Rq}cXah}aLI*gSBOxs4 z2pp*pn1Wg7G&fbsZwDbZ^9w?60a<6|oMAvm2CWSki38f7v8)h07kRK*OM)IkXnEATbT2`KD@xPD zHoLMZW=p9^&_89R=WrCms0xSJb#0<;;$r*T-LbeB=5c&i(!mr}Z=_bimj3NBb6q(H zDW17bLYI$R?Ch{M_0%J$eF=h$)W0Tvn6;xJ#H797f~qjVizIiiRV!jn)4`M7 zxy`Wxj1Dv0R=Ft23fOtB-CqV$cw5-K`=ZGA-~6|jx&Qcdc(~I4();3MR~bxZV7f$9 z#}%-}w59khBEh0|(G_*TLPJ9%7Y}HenQY@aJUsOI+j3_HzR zb#--@BpYu33(urS##3#5^~i=czv>sc!C;P$k8eaiWkF3dmL~X$<3aPU4%y$(JMXCM zXYC39FHeH)>54*_PgKP?IXM0lB%9hF`DtluBYazZeSJ$6f!7Y{c>55KcLe`i(mf2= z+IO49+ndY32j?8+v9^RrZ@_3-+jng5h2qvceB2suZK&8BxkDR!O4m9>)3TjmDDXxt z`Kg-9@SE%@TvlP(jt^9Js71ZvnqB+b<+M7_&`kOF-WiEVQoYf@#nr%AB6rUF{(98z zO*LymQGGCIW{ykmINkYpU(*)7;-AsV%&+dj53MLaZ;qTP{dOuJGqi9?-LY@GMbR=L z${oUG{P%!8n>UYJ7_UYS>FonWr>`#I(k_p+V7@de`@XoF5D@=OVgx-%nw7>0w(s(r{xjNN1nCka%SnQHr`;$tC9Z!|_t`V$M zG0K;#cwh~lv*~F2vkwo0zodWOYuZHMquO5kZ9vGz`q4S*6C2EC$nqw0s5N4F^vEf1 z!JS9lAdVguyD)-JguODogGU?@@~ip9c!6>{?Ebf6-r&ic>a9e(s<(SP zi+FjnW|}wUN5~JvpQFRpc070!=kL4~aDgjXfL5X}hq7!)q|9Sb6zi2@5(YFC^xVwM z%)i02B$GG#8`1zFp$yzjc1OrH=!R0*$fy_dR#d}smNl-d?XTyYo1;*uUd3#V7si90 z%-NX(_C7+p`p~5%7V(EEDGHD+3_`ws{}}o(kbhKFS3h`c_BywaN<1JVJRBXLfIv}E zQPaX8%Bkmajj3>FQZR3kTsRi*hlH!LA*X=xdmINkq< z=G2oJyj6nh^=ZHHpUsvP#UvK1mX;86`}$T%g$*c~ug-@983hFmX&i5s^vr@nvqy7A zH#Qc;9g&#mU#x$A8a?uq|E~qmPS3ZIFyIyO+S0j1qL1@inEgid@-Z0+_4xL& zQfvcsJ^o`1^m^-Wvt=I(YiBjN>rjOy}svWS^5vl==(tWac(^m=F8*_!8Iz4~I&9nQy@ z&G`ADMfU@Z&j)!7%{7_JRd>NQUeJY82MTyVDoFVp4H6#mc0Pu#r`!J8vMlT&9Bm`; z93a0z6b!G@l9G2k)`toJz+^YBi+p5Ur(tBI1aw3$GvsD{gRTPcbZ2H}pz3IAx|MGn zK_9H3pn!O)5nDYkx{35hpaj^Ev^O*e$VyPFERAe>?#$L=04VmQ)nAMX(6%H4(*LMl z?MpU07C{3S56)~Z=lO=BQ)B#?IwNA4>`D90*;+RFXv#G(Wak$aRy)n{$wgB_@bSUH zK^d}n9uhtN1C(42DQa8|j!2~ftzdeK=pr3f9i+FvCka~=aG5fu-@y(BMo%i%Hf4^b- zq@`!9?5v2!`REnFs7-fFM({I@O6vjQIu{(K&iqfGxV`MRUw;2DmjPLj^eaWo*{%78&aKmMaz+CpRBby<33He9V^aD@ zkD{RCaBf^9zWe4ss8jhlId6i4k>EFgH6e04;1eQDMzM6N1m#0nSp#dGj(i9NZy&~4 z<}57I$Jw$!vdcNrF1_ZQ%$u2ETM2SzH=J&7ZGACd|AF2Iwy(Js;;^tVzyaL=r}BVd zhFMJqTr=sSpIYzYr@H9rC5;sZjATo`f;jQPOwoslN+Eq#TE5LZFS7FXN}0oG8`9REIh%KU*6y`E zR+c1GbZgugtt1$JCZ1VJ9BRpz7dse?BzL-*H@KuAdFLK7j*Xood&R43-eJ+xr|Cp% zcaRd_u_~$uj6UEodKAy7s-;9R)e>+x9l7idv)@#=XY$p>XxRzDV5$7^0o>IF z>C@H+%iVUhMt_F0hGB2z{+ZD_&pL@?p@RtmKz5jKVHY7Zn9y=_dv0hfFE0c1^9Wrb zA(lfCzq`8|pfF72Z}%%AW9RYO7o%Nz*1JA5r-#0f#=hSGM#_cMQ7B!}UrA71yPpil zOtlK9^VdiJ)Ys9GF*ipTS+OaEG+^8TA3ylHpdT7(^jP=iO>@D5LEY+ClNSQRM5GY@ z+nS7kgE#>m1n$F!5o(3nJ1q)NS!m}$dfmBxbO5K`{=COZt=C{(L|18;@@^E=rw|NZq%zpbF4AcU9l2r_CZZAsx` zB15+JBZ%YI3w{aKBmgho(#d}qfvMO!*%7ny08L3r3F^#OAl!`w=oLG6y|wl9j=sWkSbyO|$e9d|}_-VOherC33a@4WYhAECIy$1h1j0stPh;`=urfG-x+|ay=z` z4oDM1CEC&=g4no-aRKUL-|%puWzUCxe~6tjIrjr>B-~ZPr!Zakh4TbCH}CQR zo6`kL1!{w7eA^O<(bqDrsdAG!4*BoEF($Z0h1~1x==}3^fMjJ)uVnJ4V_ngFnqoYo z8%WNVS60%AuyDC6EME@Tb~b8Ci@fb)>(I!AMG>T?C&TzQXHD=RBQ z4{Hst8gd>4>=Ro_C#I&VytefaWgC7RPx2T?R6(H|-iOhc_@7iWQ zm(mDm*5*jg+p1zf6->RnuPsfT)GbsxbLnVpl9gZ7qZ`A-xQX2C4C%t|Ab z`({D%VQ=b_NH$I;h$_qI*>R<=!}qxm6iy$mbIhsAxnuH5Oo z*_xP`B)l)IlwO0Xvkt$a@%uxiyPfMT>*o}el$O6gbjc6Ay$KJ0;Aq|xjjC#CBfB~e zVic!QFQJ!*RuCfJH7tHRXc;Z~9Z;e?_k)Mh1zNlgZ$U$1lJL5#tLyjC`TqH<-M!9N znlLAP4h=)AU&BIvd-kf0*(iL}PNdn0FDj_*-&RS>tJ~`qk7<*iyWZj9;R<^rIeiVC z{YrmsjHk|HF#7v=S=tH$x$xdZ|K)8p=Ih<5`*ssoTUALQziVf zOdcT8b=RfdDToj$h4rcEPALE6&}T9QimZd0lFtY z*m6B?t7yM5avSA;|7UL!h*Ma>B&Ej^KkEjDhg~Xvb(}X8F>z>7 z76CqUc<6o=&~EV-^2^|OgvPc&&XG*!A)g~@@-H8{XO1&LMrCp(A;m<#=jP`2qkIQy5xH1ET>GLICyv+|wfIVK4Gj&%`j&=Cn?Eb*AQonI1!n>41#VCgeymH&HDA3-T9@kP zW_YGwz|@>-tKZT1(zk>RlWQ1Q)A?O&pv?f?(te<-1R{Is9oEA$2+4ybxCRpXoELu= zAie>_yI*D;HSOhBi7=7#inZm^tofX!#tnSne1Vx)Ex`*ogFzqZKcP2sYAMd(XQ4eDIzR0F$B$A$*!8 zlkBEV3HPgQpX7w}HnJ#UAH~Izc9uwlRtiRHf5%DmsAc0p6hjI$H zH9A=M3&+Fc^1%NFJ4LD_Y{YS>9otpSM=B?VRs`?37I(3+pqH2CqJQX- z3FykJTi_tT!^6;^XKFeG*@OvtL;x53n9`@@cP3x-Kczq*bnp#Ze|>#NA+8I+JGj@# zpQb>5y5iYl`D+V+I-ul=V32U=*s(g@&rjDbp&QPmMunE?4it1qfq~YuYsobxE^cf~ zaD04RFyQL!w&gXHWR^+Qq4(3lubbO#fh>|!mGtlb z)IO3~<7K`j#5^1eMtjv{i!*S#w+4Z+&b;?)L_uf?20SS1aPFBwgA4uR$jHdoj<+Ze zpkzT|umzACR;$@#(p(Fos7+ox^Uy9`T4A}auh>X;p-p6|?XtJGNA!CxZRd;-+OY(X zmwbU1OOt=Tn4yepacQXxp)7<61W^Oi0!WEcP9!|9wE+0C%-;8KCkaFe(YatpU!4Ap z{^eW<>1-0zUq5RXl8X4a#*@dKm_k6*GO;E551O%kUW;+)&%isIVhvR{XA1&&S z%X`2Mxo|!k+EI*e01nty`}~Mn5x*J*+sfFS23|-@3=7-QB|t1NmR#h zGJJSFFF!vRVgkk>u@7$LD^AeoCB^KIa@ZL|O2C*iu%qSeqWueVMKIf3i4LMB!4|p! zl!n`Oh#Uwm7`uVgE4Zg`S&W?#aU=D!m7FCeHa&d+bP)<_YJcLCIW&t+cZPuW_8Iz;BRo_j2;OklQOSG6vv5x5 zHT6pDSp=V?hwO%tg<#kB@6de-ygZ~wXi%YZf-1qcy{iNT0%kSUora>oD&)Nu05xjcD zFb-F0S@Mv*Tuao)MUw2RjMgBhWq3imh=+-sII$9HTip1PSFe`#RUH_6pws3ei$dU{ zjq8+rjz0m}?Xsyxa9Yfr#5AIObtbe@_ME!|k_^eTm+-s%MEM zBq!%h+QSJWS*AA*Xp}YoTMx@ZpG`CbJ43^xfK0p~Z0??nXu|KD*_wW2whRDk} zV5Vd==|Ot}Qyg@$(9_>T!J(ul#jG>x+RMG)1qyFN!x?*7R8$Xl@V5b%SoR?TK*`6T z$wQ=x#+0&uI{iERJx?Bufx(2Q`rj)a;-KDdgn0OdNs0ZjQTlbg#gsE%WP#on|DGdg zG=$s=G~o>(F+xO;!b5>(N$TLStT%IX4?sbPfgQG>aqS3gLMX@d1eK4n%%5AKr%Q zv%5Q5CC}HvWNhN48?j5msFs0PobVZu-b$MK?eb>&ETaLBH2_7z$g85!U~A_O*x-aFq@L4tEZGtU%?b97jJ;RXW(QecTT+xI^erR(q%d zpYF|67h?7XQTKv??GOMcYARU&Tm0~^FRugOQ49cbnfQoUIlfWO)V|h;gO%0Z{TFZ~ zOn$8ke1CrcUTP%5PhI%wQ{AN)znqg(*%jo(_P5{OG+zN7rC(lFmWV?o#=idNPo3{P z)vV;K@mIF7h|7!Z3YXJ!40QA~Qcng3hDWnPBtb`$MP`qS2+=}IodFeq>$G5V$pNa! z#Pl96pp1exg)W>H^lgQq{72;k2{>I7T%n8h1f->PAwxq1HZX*IDxyChccZ*rblP z)jpcbK6v|=*M~sEP*VxI%fM4}nnuJoeJ~PrZrc2G8{0TBJv{)-^FqB#)+>OedjW59 z_xEpYu^Xj5Ux^k^I)zsfO)jX#@#s;a?O+NG4!MBF4PYK?pfVVMZZ?6+cZ22}e#qp& z+v^wqTS6QhNpCx{VR@{ABoFbbJIuiTY8U|NsjFe19~^e*-_T?kHA#uN{(W`6ZceZ& zO2;VM{%I&KI^dw7#dZ$+9I%uaSxrap`@7?X(Jc@cEy&NW&jFuzdwY8=BZIuLxL9fC zyv4NQ@bLUq)!c3pe226+fbw=HHbM*MFz7=VqiaA|hf9VJGqfW84@gGPIu1XKHw`Ma`wJ@beB_?HaVEVs`0_9&XueM0+XV@;$l-H&UhfucZ% zH0Y0vnHhk~s-O{)VIo^tTDl34hkyKUw5u~TrwxWcM2=qD`JZ&X_*D4I#;xKK=rO); zA6EegM7+7ZZV4&NfQ;9eSQ>Z2iZNy{X@ZWGF-(^v2##sMM7!WLoa4Q@^|V0V{L%2L_(#rUx$(J!MmiK7xPLpV~G<^BJ%7BGI(=8OTPTu zRotx7MN-QYO2(i?z1mg4X6ujU4!n8AsG8OVU-b+;2b4s15KvY;CJrGC9{}qQ`9sUU z94w1@9J&uA23(AJpobQ;jsPPOxGhko2;2a=g>;JK*w~I7>GwCT#oWOUcXt+Ag|}KE zsH?#Bl&S+X9jVYumFz8}-UJfGe2=kC1^X9_C+8<~!(3$6O3I=e$KD`v>X|BAr)|w; zKKwVXel(%2ZsO{K3O}rjJB^Ap_#j>{qeosnd^rMJRW=|%48{%U>tTKmXs2p5rCLLF z$|yV-5j}mpb@pJ4*B2={KH)wN?c`+q?N<7T>jz{?eA$d?H7SQ`t-~2^nZW;$-jo#t z+{9i!DJ1KZtO9QID7pPAilp54 zQ7t7+6?Bh}iUM40FYUVEl(@lP;hMf42Dx=fq^iGpU1n8b_2T{^gN#=id@3 z^!u^*@R1lwhst$GuGF$SzGbTOEe~;+Pvj>1INrS4N!|3^n>RExLBS%E@qhjxCou57 zd^Fo4Tf|*1{>9gpKh4xcPx*sht`~<7R7H|fDPKL}*Qz}6yW6AorEE}MR{CC`=u78m zKvChC$h?n1ybr7Opc8}hH{8?Q_UdJIYHaLBI((Dpkuf^wT?NYFvxAj9y)A$;Q)DBE z@0fc%hvw^tdoAs8HS{?|$J}GphkQ7cNOplkE1i6_P4HG~%n4M$|^M z)0;T0XD&|1{*7YX4$JKY|4FaOi(lQ)&cN}elD?Zp*TMyYbCd@f4F-t*Cr+gnv<}em z6p=T-JhEX_&zz^X8EepXqTgC*(9!XGazZwI@G58tkq-~pe8TN;hG6wCEV;Q(05Ti? zjVXskL^ycOcNcD4b9UPC;G=i*DZ6Qu=z4Au4iBbk8#euu^*vEpn$&l(oo@)p|CAOQ zrF#I!#?p~)T&DBdNY0{ya`j_RJKIP(3f9ElDr-)+zpYP5d5YeBm0Dz@? z<$!0~UG&9|3G@!lq;IVZK+77HCBf5k-Ty6Vy(YfM_Yfij+re<66G9N*N63(X$5{Ep z=9}4LT=WotcAewOeiDD65+8!4mgrvaV&SE2LiV+KT@HZj5#jsw!ME{u@8S}~t3Ced zUhXR^D;m#;wFccfHMHCJF>HXo9DjLp?gxfVW#4}awxhWyGqu~6Ac9c`O%5HoU{w(R zf=`+n7Fqb_)z-hLec(1& zwp8;w13Vu1;KAk4pu8`V1X`~D8#&&eqZjA``eqlv0Ra(Kt3(=wn)l1OJ=;X4Os^U= zUsDy&hT)h&sEgc$K5BX9r$-VJY8m$ zGI0r|{n8GV24MBOy7A-K+`M)b@QwXwA`?yd*09CrQO}2u7TZ(TgBj=gGMZ6x<6+<4 z4`+`*PkC%k)_xVI{+P7Of@{hBsXd*3Fg&;5kl6$6EM_qp4IUJ@N2PnJvB zXc5cPQ_(4!WC`lfPc^wSZth->n5ca3`rE%}lv+;gRF&QKrjji>*xz!(sq=|~&|E-* zAQY0JM`VnxiWgi%rWH&yG&zcSgGqY2QF7m4XoH|PTR?fsGR1>1$_xlTr!Wt2tBV{U zsf!*Hf``U4p~n??6B19gGCgG&aN>WLbX(+L zaOQ*QVmda(Smj*2Ya<8Uqq2wC^78L++T(Y2#$Qvmwuz^viYltM1|7PKZf^eC9Jgh! zU$|h;(ZH=fpYNVVy(^cP*3ap!q3O$ULLJ^#O-Vx(*Jd66=r_*qn`_cp>@WqV6z{6S zH&;xi5^FUpEi{hoTb@Gw(lq}p&N|TbCSp=ezV)(I*eBIKwj0To^AOQz1d+VfvuBIN zvqT-|svZEUkNn}fH5SO)y#@j45r8X)pg&{zYf^+oi+UFUVhMVDLh}-XG&&%#^rCOY zA5s7Js|jm;f9a6%uQ9v5XOqX4yw&k@6`_aRR-sy~i;i`pWpf(VJ8=x#seDdiy0;ar zoDgCpHXTqy**9hJGJaL|u&u`%UuxNLK9~`gn&dDxfMsOP)K2=%*qfn$+=JK7?GM`A zb2L(hLX>|hvBXHB8`3-{Q^*Jwh;SqB`Ecr!Y~@hR=djo&PWW--jNDKQpTn*9N&JKL zjg1WhvA=&$IfgG=k_IGQKT%t-SFzv>U7uGu2KqMr)*9C$L$!WI{CRpkt0;cf-61OD;#kL`1`qCMqN)R9v}Ah_7chmY^rngO1OA= zLtJ?N@1~i1zX+yBb8#-jmQ>i16Y>=!CyJAitFa zXV>qu1GRoPa}}-EN4hxg_L@TDF1Wc3Ar4o9*&6j-Psh4@Y$hezLSCXbm_yE^j%avh zv!B)z2Y+~}#fJ3*t}YBFQHj0Qm)skFKlzsh_^8IyQXc?J>Ae`kKYwOH@OU=l67= z1TQl-fRchj_8t4ZD&^@_Uw_mle0ATCXxm{f)T^HWjKe9gE`W?-S!qkrStrksSa6hn z(n*NeeK$Bb*j21svYdH&zMfU+y`l)|(M#}shqEyy^b$qNf*&75v*jCNpr-(uL@{7C z1AEL8kEl?)BssU9zbehjCfvO8si`8YOn7TKI;?%)sUQdU0~eGgInXviUzvwte((}+ zuvfy;lCHmhK*Oj=YPOO~DWemQV816{tJRdV#^{lf5=V0&J8^^_y$Z5#^26h9B8@*R zbkDUQ4F=<_-o4#;$Xx~6I1-ZAR^;3`kGwD?~Og$>2u{+6Px*d*3 z#S3-Q_x1B*`F`gqzE4WkP=AVb(88u<((8-tr;neTAC11q3%pqmRNI`bgc|V`wBUl< zg1{oO0D|drTusVJqf|oWZh``7}I1{RcA z@QA?y?*n)*2uaG*ylLb6@P{-q2$1o2*FGHQfeog(I7yP-6jPrkRX`H)R3@Gl6k5!fYIue5Wzc$ z#4`F%BeU##OcaM+(&FE*XN@#xkJR=#qd2}8mQAZHxpnOYOUdxYaKsanJXnsNS$;30 zkpDo00Kj1L{H(_`{rH(-&u%ZKrw4U~;U*mr+aRv^G7=IXf>)GXQo?4w^MnbLeinz4 zvl%GdFW~-Zxw+W3qObxDloi>8BcF8MD3~_VJsVTHy8c+N=kZ9taYGT!i&I4XIyZiA zC5KYs42hi>Lm;`Pw47Kk8by1LdiA-^dHzR|%_zmFs3=86oA2LxdljDY#`!2D(f6(# znDLOY)D|HmUcf^tZ64Wt1APnC{$Be+xIX+D5FtYTU!z2 z&Pq5q?-kefAx|>5wUq+?L*VK_8p2M8{bKiaIn~N^Ph(oLlO%VzbI`iqzEDTNLctV>c z(3BSNE?hv_5qB%~)D#G@(f3QJ1#btS0Kwq{!Wj5~VF7AJQBex~Fr?e_tXnh)h>sS# zK!r;%5rcarP~}%(fh?R9$xvgW+x9AJLN*V6JeMi)^l;Jt=D+fgaaYGzn0%aXELeDx z1oNmuh7^atTy4mUHx&;H10dc1SMlBWeVL~Q^>a~xcw~tB5d;6C-pM|iNKLlSmZ;Qg z#r^N}^ojl1&^y4$zFQl0EjKMnz7CCGzz-vR!Vd!n>(}t@J0kE{t$$;XYth$ z)|x1s=7S%H9TWPLhb5f6#cHrIs*u8-&mwimGkdNva@*HiOrJaR5KjCimZjM}E)y-Z z>j6oex-tt>1n^R3!1F?uw0bO_xW$(`$ko!QB{Gakn*Et$);8|VFBN7o&Xb^CvW=ac*R*~|_da`W}&fK>n@J5*F9yI+@2Y_~f= z){b-WA2lO!Js14qK2(_BKEzBp)h%UEomQa@cXHLqZ~O~uAPO?RpTsG08}FO{@@cM3 zL>>z5e;w4Y=qMvp6EK)oQ$OO#5UmSVQ>4xv%x=P`ybv~moDb{%@*T1}m!Kdr zBz9l(>F1s>UEnry_lR;3c-(rvlKJ<>j9B2!2CDz0X@x5VJ?UTlITUO^$vRxCbGOL` zuR2<>PBfZYWj=so9j|Pz|I86Pd-GH7(XBZ)L-4v zYNQ;mNezn}UquKlCNb`M79{nXY+z78yIh(;KZp@WG`Pl$po#FU-=LwGA{rqm&ciWe zO$~L&P_eaD$3Gw-`Hgj{=};!$$o85j5wnYtRTocwnsZ<@pZ8Y{^kUx|;fccq58K#8 z_TJ(>Bgx-{RbZyYcP0v9T$sd*jqP{zN1|IU5>+&VEKgkfrl_74ivJ@%{v#oC)B zKb47B1p)s2Q$pd{@9ao-G6jF`F?z%kxdJhGvC^yxKihQk=AUNHykG5{hbEv<2saa_ ze0UPFO!!fbUr@ivC|Fc(Utc=Plp|BbY>%`nHi7-diyM$QK{55fPg+{K)uR@QQ%;2| zii(Py566!GqUQ*x#Cj)0FL*!PPn?kdSP36mVpFwE)+nN*11}6_ds{;--2vob|r-6@o(G-`*Yg6$iV{g)h9!^(d zFKrWcd)B?3PUmNk*};P@-rjPHb^kGSj4nyOoL>bnhdyZ!F$ML%aKYOBbWz-OYcSX` zT@*t-J++@pp|pD*f7{nR>kGx#KH{kY<^*88x~QF~7A@J|ko%h~5d{q}-fmx|8;{yP^yHb{B(zc{ zG5TlEN>7LAi)=sktH!Qe$>*^o%o#n^49nh*C#wNr4ULSFaf}^Iu!ZI2toSEk+X4TN zj{24wtk%|SFJIoFPMDC;y2x>IK;QK`NK78W4QEpQVAHWW&iAH;WJ2;WRoW(TM&bi#$%gr*8_KI65d=kmh4f`4A=c`@FhF=@%t{pqi6?eaVbBT0Q3Yf$= zymln;25`(MN|Msfc1g%X2Q_rG+27P!gln&t-Lg?s)WQ=08a5#My~iR6bj`=k2_vQNoi?Xb}25Sy_BhgyBaE3 zqxwDE`m^^I-|%sAavD9LkkcOnKiS-z`W=ujT>twk?0s3T2CQ zVM6uQGcwv58#@>N*_z#s!0C!yHQrsPt3wttlNxJx9^i)n`prWbGK2~ z$X5&D{nPaIcNvn5_1V+5zuoC0T6Tfvn69vTUGUpPSrWTK+{vu=)i)oG=Bf8#aYLg3u=6=Ff0)I>BQ zs7A#V8OCA}{T}hA>Q8WsFuClMS5~HPbQri(H?tZnub@B!84hO0I2~lpKkNDYAK?sB z;Z&1vQ}KtUs=F4u-k)F6H#Kd);8<1>p4OmbJv~g--%_GlRAmv}7NNUlXYW!oQpjjO zVZ<&h+w!q$`}ZjAu*-Kt_a{7SN-_P_r#CxRKhc}CnP8#HB9);neu#=KBi30cPHKgu zP~gIr7xBjR{Cl_8N9?@>MB~*+|CQ7sF_Fsk55BU82 zdaR~uWN0WHqb=gf|NL6IyN=hnk8wEb8lcbLeZ!b4<}Ra3PolEm`U;ILpQ1 z0$~GT0XTpGtPK-Tp=4t@4Gj$yRxz&2moMXRiQ*k9IsIflzDQdcLsY%SBOhn~E2#Bj zP*W2g-fLNw4m-V*ZrNU(LuSy;yY&Z~MBimzy33kYg*SU=Berl|x+0jywB>Cut?ned zt+Q}~oUIENyW8!DVcZ6$vMQTpXOBo`+c1R>Bx=i1H4nz#H{rOT7SM_i7&XReqp5lSM(hVXTpTST#sw9tW zBJP>MwOHV&ib@(4;~O7UW(Jp8+P&%r)wiWGVu`^(03H8~NJ@Tw62t;96L2eJc?KSN zmZrI|FQRKYywzDKvUcvMhN>z<{$MP!Q&KM7fn@i~DV^5+2}$`eb_XvDt*rPhzqH!@u1wPS*uxthu1baC7yYQt(q^(Py-GVB5+Q5Zx{H*rA)_ z>Tto+CtT4_lGDfLS9N8$6xSOa#dmAYskg3$Xf3yM65rPy*a3>z=-ycx9d@F+3tWua zWypPwIZ%~p5b`BXP|*2(E8jsyGMbB^4`6cR=Kz{IHd_%93aFtNMNhH zh4-G=(LdF$*@u1!f1nOzJfh*cefPk_y1GedM6ZT?*thhUQ>73Z55hJ^9Ps15pV&{J zCUSphR$?^?wQjMa=$GS<94gW}!)doK?m(#=Uy?X0?OIL7hMH4%VzTMb3QY#mDE&z& zki@;Uu(FE4jE;ch&}~b6vO@`CYOH|tOH_1uWlckaLgwY&O69HUX?Alsxl^9=*vJSr zeFN|izP`RKuC+I;|F>ngI{8j5ReZEcYLi*{<*@nZhvpFEK2u)$&i^F!x?)J60p)j)X1DoZRRzd^wS z>9FUA$2>$_!P~dwW9Oj@abNmvhKNPY{K2=G=?n^42}j9hF9-d`mW0rABCdviw(RgO zO9zL9r%yGZr{RFSN~9i|1rI`Jz}3B##tPmQbNtkB-_bJx+LAM(5=JqY)(ZdhnS6XI ze0Lffbv*OsZ0={LHT!h6)~+Zwc(R!t@hoP2B>aG$cmR{%g?O*cMd|4Ts^8yOJC<|q z$@qjQeWxt@#cq$3xy;epQ^`xvA{5`LG`ga4c2p;`ny5k@uHkm&rI*iRTp7Dfu(Pc4 z=`~0iIjE|q^qyX7@9c5QSXU4+ zXcWs;PQ4yH@Z0)dEc&-3Z6PWc9RR`jRlRXetU$DGVN3JB`Q{Yq7FZUDrwoV5yS>Db zfS1-Loo?hvQ@~Q1U-%xxPe+qXt+*?l#w(U@IF^qpO8$p|An%nr7L7l$+POCq`_Al? zz2r~d8(Pg9_=uTP@OapTm(kB+GymFzhb0xnvC1huzWI`MYJ}_Kt_ubRTW)P?zR-?n z6(V5c%-|bi=&TYF62kgDrfUZ^ zO@lY=Amap4CbbVWEX+an&^7)Z*J>CWCRc+~&;0Mp(o)yZEhFJ%<0@o;6fbViq^0+T zr-MKwnOdQm>ihO>XN#?dtmZ(>M+hkh6Al#8rKP1fSFXGC4k5pVhrqjWf6!dv_|)e9 zKMcx$E00VRbAID-Bnu4b)L7AtRZ%C#mp%8p!Vv$zSGw=Z4TRX+%e9*Rb6VOTogJYb zmmxj5x?W)6uJgUu-rK#`QfXIKd>q;n9r|mAv6hkfmw$7w>HX+qME%03cQAAK=4m02 z1i&GL`{2~mbwK>AEJ)g+eFx-mufd!cp`D^6CSelOBvjLHK_%Q@%tT(QgDjz%&d$!R z@*GhB4ridFQQEtAvcCE6ZY~+ymbK&JC}6nJmMpUTY#=$r#zNa51JlqT2msy=4Ri*h zjeh7#pcb`|B;lH4u?kbH3PK&tGq2&7x&;MgvOIUAy)P+y{BazyLTsz3=ybsCxgh-; zFDkl{wT?Ykbk0_$Gw%$#6D-d)bFW(e7z^{`iEBaLT+A)`KU#0k2;Umt8bZx293`B^ zLOEh6foVpilr9*67`+9Ee))i>QYnv3Y*d@HnI@cOG%TBrQh{7})U+~CUF;xXU$ z{Mn?l2@}Y{wLJd*Oxk_7vpB9!dpRTj;zyp1$!(!6=jz7{C&hRY4HFU*(fDH67e<+c zoSGk5UkTE+FFuPYTBC8ZyM!Shl73reeJ59bgLbsEwuVH2IcrVhV*mdW@ctY8xKwD#tyh=;7z>-k-9MYq7rv~ znToTtCiG^F%RhexLconkC^~ot&^_xqIqB=BbxphAun|Rt8`Fw~kLMr`?!dm)pmNZcGc>;)s@!P>?v?!QJicbO6<@Z$q^B zkkZQt+1eLgsK&NJizgvig=9kPiiH5;u*MQB>dTiTCMG6}!-wer6CXTKf;zMK=;_oR z{j zpKSBnv^wlSGqpzxPwIikMeR3eQu9>Ksaf~Md3JVnO#S`+AYlyx1C`aR|3P1i54)H4 zd|D|4S_ChIx{{{0NN5qkv7`)NVNdrsumyW4G2b{|8GCq_0er)aqQ_Z3Zm@C0FTAgJ zLwZIUi-i!okdan1LgwBgVMASAo%|v#Sx4hD`nmI|B~1DbS>t~fFBCKLY{N^YBxt`Y z9a8=2WFvuAK-sO>ufQL*d|Gh<$7mDaH0e!-EGz2$LMQCCQ}q4l^|e6~U~&nWHAp2n z=xkE7_F`pLSIc9Pnc44wWqIGBF{QH->$_;xiy((fo(eE$^hW393E*#GfF!nYJhhe8 zO^7)DkBB_5yQe^EGTZwZSN48^9-jmY4BZM5;zQ_0Edz3UXLau$CjRV7PuX;}(ZSna zJCcCuif>H?KHT1}KdN~R$HNj{!UjmHQmxcv_UyU+H4Ta6{!U0^i9vHous#6NHjn-K z^i}!IZAGDNCkzm%xmJjN^A8Mko$gHZ36;QIfd5P9?%@=gK+uO>NrFZY=Ng=L+?8I` z*vNwbkor+y(_x*uqh-+}o-u=;L_=Oz())erpb0~7OdQl(Og8$ljejqc;7s5LAu=Oz zaYb~vCT}T61*;L2J}mRHsL1t7U7>~fgWC-QF(b{n$N2< zbvKN~(mD|J+v+S=fPM_PaSg4RP)2Vx{4Y@y7pv}EM!X1!`(pg0Bp$EU9I2$Df-*se zH?1}gp^ICtg70~=qrVit1-3o(XI%l5Fa`r~hct-jLYE7l$IOEf+Y+s6TVzUfOIBAN zEi>7??C-DSC1`|E&%q&RSf_~ej4MBD^L1pnrZJ^+xA^Bs(1~~M-VN`a%}#%lHpdGA z95T{yO|-PMlDl{B92s3$SU^B=1HuWM>+E_iCYX`QWQf4c?ta+5%`f5%$2L7ZJxDl; zecG=pUbk7_prWE;Jz=7+b2xg;D;6+SI+%Uz3nY0`d$*t|Z**WQu`)SUU8Jdm?g5(+ z-elAQBzzJ#1EK*PF%DreOHox7J35iH|J2m4tF4dVMu6Q+C{s?2I*6;uyRv>-LGKmd z3EuCh@i+C+(17Mb-Y(U6GYIUUxZ`~=V=QcJR#QoxoraJX3lfK1g93*`0vZaQ%7C3p zX+fDU=zSqE9xex9Mw#&_mW`#jK=J=>*%qzCHEGJH6-#@2Q#LzfH;Onu%u@0dNHRKY z+7I>>1E{PseKYS}D7MdfLpT8k<02p)g3%)>+?< z)$?ln=Fc=p)uUqAD+c5brC01go7M)|vXla$;LfjG4X7x9DiPY;gOXeAjvog=KlHQ3 z%-p=qT>+#UJ4_(vw-ryw&j)3u(sQuTI;>2i?NPvl8<(Cgn&tfHY zyVn%IoXN?~_WnL&@_lL6x6yl|g&MNm9mgwwWhYkWrP2dlLfAE^ElCm~vkX6UhZOLQ z;Oo!+Gv=H-lF&Y4riwBC$r6umzc-3AOD*-K`>Nwq7$pB24c+`ZV_tvWsW{_FX=%)` zyowFfPrp)j$<_+*-pvX(8t^JnFeFL3*zT@;ixiwdIG2>Q=ah>%uQ3UD2Fm6szZi;3 zoW6*mpueXl3&+){(PJ3K;pwT(@3)lSb)>%AQ~6d|S^RJsEE&RF@sokKHO1Fq?0?%7 zAdNQk`OBAdiH4DcBpHf^0!}oqN zT^t$BZ!26PJ@+kC`91pP$Sm}@W4^!Q*tV1-jMq{SNeyoIC z_R)i27iw!c3FLxi4(U+%78CyJg>UAoeWne+zOAN3LJ4+Hb98SCGrnr2w{PREL8xrE z(n@+$r5TnajlRI82q9x?s?t3Yc-betEk6~KgwdtL}%3tNGblNMLtqnli*?Wyg{LHkM6;kIIw9AJgH`FYX1oS;d8a~>!k zxqCRG zm$s*0w1tL$3B12sj~co0r+IT9E^gs3M4@e%CFmYm;bR1W#VzY#Y`nM0s_!B#wMd!2 z%*eUmU|y8*VpGz*A*7^+UWZAV`Ahe#8u5$qmC`07(}>?)5a+PR7XH@K!Zj6vAMLd(UyYjNTIWk|OzQJ?_~7 z15T>^c}J4vvgAGRaPWJw2YT*(pDtRyGK;z{LW_DY;)2QiHU^mC$jOXl*F4M!R0jvh0 zBZ7A3_6zw=1_%c#WDm<^cKi0Q4Uw3lAwp>x|Myb`AG`DFOWM5|7<<-w4qf^F>e#PF@sMCev+4aGDQYS3TEbZO;@G6SY3p`ysxcRh8|?% zg6Fd4RPmd6SRQ$v8}enl+5|O^Z-d*l$$iN0rnz6bRDd?mF_nLnW80+oXsE1sJgbW z8a$oy9}I}Z#t$KVN(q1bd1-4u&Sf78udynBCjcrOKez>W(~sqJ_w=-4W5koBLYs$M z(Bo-vas~U-yX!(+@jdGuW;;o66TJ^uUtjkI>-#;gZSvcFum53K1%2$$hY#j~U&h)m z#PYq?hRG35?O0+&4h|2^Gx6;^lI`v7mk(|JI7EDHOA>en%w#bVF;UBx1m%A5%Kb+q z)(s2@XE)$8yRlD4sUbh{P6L)Bq;T|FkU~`+dp~#3LCwpSRxS94BrL@&XR zP3GazL6x_&vm=^qyoqRg?3T1u`3*xt_7PbcRwt#HuhABPe9B*wM3U!YY* zk!uB1K#;=gJS=~JjBS{|JIgVk9ec_Z(BbiLp;PnuP~U5C0v6WRdI|~Wl=(0--3kZM zT}mH+pc6t?_62f|v*J0!tbj$=Wqn8kC@vm6GQJdeGC1Xs>XX9q7C#n$?bc&Vq-*r5 zVaENs$rek20t?s?A5D7-RLKUcnry89ypt4l{g{`;XK_?Kla&mG^J7q)HD1yXq z0`fyKE4q7^5dfVS^kLZ(bQ~B5-={J9BH>-rtt~B7CVw#wK%YYv6f^?28fGjn_e_;u zqSGob#=+?nxKWr3mo>JC72sNs6Hzkpd>Rqbd0zbI*mJv2aERL5OH93I;)Cq~Q(qQx$rS zZIR-#z8iA=u{MCvccnfmWt0T@o`K%s~`h==YyM$GZ6Bs zoyJ_Nv1*6JhmJF1E(`hLjpSq>MYcvZ?^LbJtms)V5%lT*;jD7*o&UiKKTeyZ&22Q- WR$SYwx&+a2QJEN+>sRPHNBkf2wlw(w diff --git a/third_party/golden/wikimedia/chess_knight.png b/third_party/golden/wikimedia/chess_knight.png index 70a4424395d9d5aca3edb5980d4e35f1f7a49dab..87a747cbb55cd63f065f943ca5c0183d384a9326 100644 GIT binary patch literal 4757 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 literal 6839 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 diff --git a/third_party/pubspec.lock b/third_party/pubspec.lock index 77f3d0b74afe..a061c5fc6406 100644 --- a/third_party/pubspec.lock +++ b/third_party/pubspec.lock @@ -7,7 +7,7 @@ packages: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.33.0-alpha.0" + version: "0.33.0" args: dependency: transitive description: @@ -63,7 +63,7 @@ packages: name: csslib url: "https://pub.dartlang.org" source: hosted - version: "0.14.5" + version: "0.14.6" flutter: dependency: "direct main" description: flutter @@ -80,7 +80,7 @@ packages: name: front_end url: "https://pub.dartlang.org" source: hosted - version: "0.1.5" + version: "0.1.6" glob: dependency: transitive description: @@ -143,7 +143,7 @@ packages: name: kernel url: "https://pub.dartlang.org" source: hosted - version: "0.3.5" + version: "0.3.6" logging: dependency: transitive description: @@ -220,14 +220,14 @@ packages: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.3.1" path_parsing: dependency: transitive description: name: path_parsing url: "https://pub.dartlang.org" source: hosted - version: "0.1.2" + version: "0.1.3" petitparser: dependency: transitive description: @@ -309,7 +309,7 @@ packages: name: source_maps url: "https://pub.dartlang.org" source: hosted - version: "0.10.7" + version: "0.10.8" source_span: dependency: transitive description: @@ -351,7 +351,7 @@ packages: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.3.3" + version: "1.3.4" typed_data: dependency: transitive description: @@ -409,5 +409,5 @@ packages: source: hosted version: "2.1.15" sdks: - dart: ">=2.0.0-dev.69.0 <3.0.0" + dart: ">=2.0.0 <3.0.0" flutter: ">=0.7.3 <2.0.0" diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index b20d6e22d4d9..3eb4966b3a59 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,11 +1,11 @@ name: flutter_svg -description: An SVG rendering and widget library for Flutter. +description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.6.1 +version: 0.6.2 dependencies: - path_drawing: ^0.3.0 + path_drawing: ^0.3.1 xml: ^3.0.0 vector_math: ^2.0.4 meta: ^1.1.2 From ae71f6901802bc75dfeccc56e2e38ac70584b731 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 25 Oct 2018 11:04:53 -0700 Subject: [PATCH 159/512] update golden widget tests --- .../test/golden_widget/flutter_logo.asset.png | Bin 11111 -> 10317 bytes .../golden_widget/flutter_logo.memory.png | Bin 11111 -> 10317 bytes .../golden_widget/flutter_logo.network.png | Bin 11111 -> 10317 bytes .../golden_widget/flutter_logo.string.png | Bin 11111 -> 10317 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 11653 -> 10603 bytes 5 files changed, 0 insertions(+), 0 deletions(-) diff --git a/third_party/test/golden_widget/flutter_logo.asset.png b/third_party/test/golden_widget/flutter_logo.asset.png index 8d8d2c65e9c990f9717bad016fa762604a2965d3..3047bb244977137bb504f2f6888400a95bd2cc8b 100644 GIT binary patch literal 10317 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 literal 11111 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 diff --git a/third_party/test/golden_widget/flutter_logo.memory.png b/third_party/test/golden_widget/flutter_logo.memory.png index 8d8d2c65e9c990f9717bad016fa762604a2965d3..3047bb244977137bb504f2f6888400a95bd2cc8b 100644 GIT binary patch literal 10317 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 literal 11111 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 diff --git a/third_party/test/golden_widget/flutter_logo.network.png b/third_party/test/golden_widget/flutter_logo.network.png index 8d8d2c65e9c990f9717bad016fa762604a2965d3..3047bb244977137bb504f2f6888400a95bd2cc8b 100644 GIT binary patch literal 10317 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 literal 11111 zcmcI~`y*8A_y3+TF}+h}=tPCNAe>YxrzFN0494NeBu1rNaw`=n zBt?j*$*A1ANQ6Wox6b4??%%cdoX-3G{R2LJvF6!pz1DixTF-jc^X$$0-Ns_!f0q3R zL6C)8EZN%;M2dz`=Cs|u|65)?Sbd5w1Dzb%bvh#HEU|Y~#&!bKs zM4t-Aiv5R@r`EL=%dT7e`^Q^V+rw`2{*zc8mGEBAdh+Zwp7Zo2%f_nRIo5l39Q)|7 zuX4#s`p$RjvLaVl=R}y#)4o;Q5Zi7=_&!mpB!La|+zZ<(-R1xICx0UUp%vT$8jYkTzy1shy=Z#%9 z-rw9F{MI{oIC`@upOCbIi74raOl&&Cf)%KU>_stEQ)DtXpM*$TaAGfsos|egB#h3e z-onvU#uK=eB+3_chSCxozJeMlcS4>b%SUkO;{usYJh_N1T%_SxXIQd8=9vZ)>0O1v z9t7AC3>F9S?POG*$^y>y80R)n6<~_0;_iXx`!W0uT^yd-!$a|Xl!45Ykn%vfNys(8 zYa@?hbp(TjDQc*N6-S9A#J~&#dn->xd?V1=;M{0n3;{JpsxJGFKm_qI2GuV$pUWht zEF~e^6)0bJGK%-+1-%lspYCriw7@&5F%iqH7)}(4iri4g(9OWqH<K2^j^XmxR0om>v)PuRaUfj0T#+Jh|QlfToJ6n*?U{x_#=V}6xX^X+?`r--cXE9hN7a57cPNg^DH?;-<+& zE@CEfhhdb5nOHFayf-8WhX8>k!99*AP?uub+#?X2B^#YCk_0oqD1ki!QUpvY{S26J z7?aYa0BI&6je*pVkOzRACn3RH=Sob>c`Y~}FEOE$NaD_uc;q>Fbb-X&C@{AhODv=X zvZ>n=v!MlS=$4q%0{PgD1p;XS-eoJWS#AO_X$+UC3W_DE8w)GKor}5u3jnN^V4VPE ziV|gKU_K|Y`oV1l!!}`lWCr629p@#pTn?j4C8PeJVTXj*>o$~CredVr_FqNwML0CS zAIXVKtTY&+fu6L94d{@D12Rr!SRR$9JQ=;Em{Vx9m|FmfHAxhxBitBRNkR#!3d;uq zxLuyYv;`GQJHz4xG7W0rG8QNHq8JG<=OU1T+9KRYEP|7^l?+;Ok+2mEONg)03MRKw z9z#u4pjJ?MC{zVPBsu#CWVCs5&QtAAcC6zkk(v8_z!8zMJyzimr3P3?ae^4>cu>P-f~(fGS_)?j``9AG>q5Y?gBS%O()JmI1| z#T91wNDGIb&y!mRGt@KTGS`7hfed0zrp88!scIq|^AbowhXGOzdcX=c0BcPc5_&}< zRTG7TF8PPN1f%~jT!m2ysq-fiI!^&p=CBxtUjSVYfZemi6P7?hz92@NUlWKrP-RhV zP%mpB)lhODkQXH6RUn~3Ku13U87d*A@dUJZ16b@|NGKF<)G}8(6D{88B$|mNw0NUZ z=6C{Hyg?ZimLXcaQK>{E6pALr@eYH~CVQ*cyg0D2q%sycLTZmgfdNhHycPr;p9@HTs}4>>7#c19jKD zGhm zmxSv8k3a^}Tz@l;mB%BstY9poGb}AR6%#~KfNglgl7A&^xw=GpxS0ZFA(^5M#{y_> z!e}gq#XlKV+i-QY=;3F6GNdoXhgXtmHBn-BSTHmZu9i%dy-2)vv@-+JFkB#`x0S2w zKo7qa$&ZMXlb5G7fH%^4q}5g&JxKppF?WIl!61Hq{L{t+3Jy2Ln2v3o1GBAod7 z!N1R+WDnw)OP);BZXCMn;r&GWI_Lgier)_t1ELN}6BbSU|IO}Sjz6Ux;2LW)d{L~ITR0o4y?Zf+NK5W*RR91w=PxJjiUW2?&`R9Be*m9xc ziJkrFAgT;3B6Zf})}I1~uzbRZ-zYydoFG$uZ0I+Pe_B{=!L67V89VeZfF`V1byms0 z08q#DnBl(spA#;gPjZhWep~bt@P`7mfl9uZ_Valgm6?8!uD<5y^Ab~Tg>qyp=cmG6 zIEJ32vwo2NiFtY;T6u^^{|lhbbgpAt2L3Cs8p;@zwZ!)4l)MzE_o#H&VGAi@j0`@^j)m}v$eieyUo1HP+ zp%$MT%ojg;WIr>|^69qKnY)9>p`vqV$(x6l7RNO0#zU7|$=!1}& z&~nR@Xl}rFQlD{)P4pyF8oaMKo8Ygwq(qC|>$Zr77Mb`uN*h7|NIwNU)o;X3CmV8-^z+PKTqO&=AZtbGA z8Z7-)A{-kw-DHMEB+Tx5r;AlM9O|VK2k^bJhk^NstblS z8QixdYJ(ajuq($cZDxA?rz^j)z{Mpbn7^x%K*nb;#7!>f`Q};QiK@}F?MqHQhK*$# zc-L2(ab!h<4I;V%Gq3&zsVpn!D^*q8?J%_k{ktw3GpmW6ur2bscr3+hD9R7Re7(phclv&|Rm#MU}>g^;O9C z^*f~;2spg5PaYBcPNul2p{p2yYZR_pOcX>_S#+F%E@TI(Q(ig(%3@5O7);Aee+LcHm zpMXmx_g7hiIAkP6oDjCX{L#D7%)aebqCI{`;K`+{8!D7}{7v$-9y)_tSbR_l+93yo zd}2kXRCPt|GUr7CA)Xhz1H7}u>m9OCfdZ9d9FB?GT5sT%sWbMfvtq!T9#@&(|%;kTvm5YXGU0nDy>th_hNfnIIepO$JfCYf`>T0 zy}Det;xUh}+Pfz_QZ7BpAY^!+1MD$sMm!Q6c6YgXKL#H&0~vuo$fL@l9&FspEsW&jtT5e|d^hglZs758 zTbH3vuj*}d;1=@a?qi}^qgPilr8~onwm@niK^k!MRiG%pK7m>V_d2@nonZH9OudL7yo>Unm^X5qYd7|68T^V6cRXDN zH2^1j0Z!Z|oQ8x5RGlfPgT_a1=udQ(G&ro~@#MO@lhI$$f-$|}mzO-v?&Ws&&heQE zgALaOMR5ME9ttTS^ioBYPvd?hZExx)=bx-kyW`@L**>uvR5%@lyGSUO53c7LJI0^T zh}q|)%j3(1yp86s4t7T1jGJyRkjXJv4X&(!%hO)CX8cb9=tN>ja4v^~%C1uj~_R-OF4P_hBZmGfc-XW47ORx@UZL;_Q=eRdeovI%rp&uGsg=e$G!tbfHj) zD=pnzA2g{r+m&{AwmFUSEGKWGoL|*6_e08)KcA`qNBgH|_a8{Tvu0ID8S$ER>E?Ya zZKpd+=UfNJQr1LAYUNKg%H>VJKg%Xoz^*wG0X$t|@r(N0w(^;q1x*%>L-xjxCq;7S zNYIDkN6rziExeS-hsVV;if(!F+s$~tnl}!u^zxh@%8Mc)z!FP5c)`!VaCfTsFaNoT zzClxw-7Y(;U+k>n)}6DvePE)x`}<5b5f@o?J7)j{?AW)j*9a`M$z+Y}?AfG!AJZndUbr2* zZ1%3_$I|TQ5{WoC)gxgVtVi)FgSD6IAAc97ItKQQDc0_%c zfnUeE)NII<9lPG;1+@>Q&DfLiBbQ>1ALl%tc`;ggwlgD6>r!I0s76?6F{tX` z_e*Blg#O()aSP;L!wztdA^GXu8S$f&?%ggS#k;mW8G?{yyvjW!PjfrZpGnI$BQ|V> z3r;rCW%I|YE7K;5DM2S@{=R=FQP@}2p5~U9;!|g#k~tXda#`y@pi57E$d+&<2rl4P zu&eJycXe5K<*DrP`%Pi#+r##avkboek$MZ2t}*@k8sWj4f_|@o;P=~z4a;F`h#)S# zHJB6KSU=tR(JRmB)YJkwPDTr#KVvFw>)?0lbiL5*7GsgN-PQTH08=iaOlL(L4m{>E z$`2Xxw9Pd-)#J=jZuSWl+m#lam5mAcYPh`4HYcvB?ZZSe5oZ9mF3P6ivd^&WF`oLK z=2#l2#W=DdnR4dcklr?%<4@0ADxhA94{ZC5jQ34OaBx2OR)mJYcCO}0X<4v)^RC1? zuefis{6L-3q-g$&uV+@$3B7Ow1}BFbX?}$p?HM!eMeTb+`d);I)*89$TE!`u32GvS zmkacYX#;CQ&YhXaP?6D%($MMbT9o&-+8!WZ^%lD+DMWw!bUWWfvw zrv5zg8#&DL0n=w=s)W9I7BvGCSt|k=*SAe}>WT6{kjONqB3#MtfEHy#3_oP*T~+>i z%3Da3S?!*+Z8Gv}o&G%K+Po`Dls{f{j+E|#-Ok2(wV*lsE^xLsB|6jViR)N^cB5;R z8vUiaG6fu1HJipy^=S|049pC|G~sr~$DDp+A53#MV>FdwXfT}b|MZOD!j4*4y7&FF z&s3pp3DX`fV^5N3ZTAYw@_$&&eUnKuFc`KQv(e{&%kaDN?Ywa9t6aK2G=!w|1z^V} zUTkY&(R=&3-pr7WaB)Jjk7_{=N15@N6M9y513MgPhKVg8(KdN{=i~+VWzLQ6SnmH_ zIg+1s>uSw-ytB$wR$F9Qb4-`q(we2v%n_=$aS_K@;tR-(pwS)1qf)jxpUP%Br9Npj zexX(-co?p^WHETBN9(pF;;hf^oKmg)3-%d6ay!}7E_vv4F4CK?eL>o@4(d3XA=?d+@4ep^cGF!|MH<_Xc5X%gug;@9k&*Zu=DCKQnac z>=mcWGl_huN-SI{^On|g&RbJTHxILhgBP6CkVrjaS05Vm$jO_oEPXQf?b)l`mmZvL z_0w5nZkxvzElp1SzIOBQYg2FmT-w%z68D@>$r-(DEarvGj#TZio&Br1KTt%TT2GOY zTbc|jvb4u#`c*;RgRG+aBoKmkE;T%2V%~8M=hNHe{8l=_v!X7H^!~?s(}S6>-jAyXMQve(89V7F#fh$aE9Uu z$q5%(70JBVBZJR{Z;SW>p}zhh@9wUO3_rIcjIkq3dQ9R(uRo{8Fu)-kf!khqr@>0f zFDovb1nkUuXaWB?l4h}K=&1dA(b{I${T9k6>nsj*xg6I>2I*V(DzGPX!syhDl^Hpexi4W4?Eefuq!oBH#*k-$@jf3&+z*2KFB?kxG4p^THiOhzKF8v z@8~k9!>O=>=N6^4xd->gR<1T4?5n<8`}}%W@2mK{(%>_LQglKBTmZm1_k{Py<;PY& z86Nw-fAa>$SgOZwZJhGCtTuha;kC0jW4=!$G#9<`@l_tSFWVlDHv0(L_7*)XFPYrz zJva0)I@8;Du41FrDc5eb?3w16vXEq3ir*>c?u@OKWIKyrO6?A9%>K}}`J<}|Y?l`B z66i4fOM1>|W8YV{_>10MHSTo0Mvw?14mwmmZe7lr@J$1s)QqyuLb-TBcEz# z!Hcu9M|K`6Qhn}Mw)o?5Z9kXAN2_#L+)a=JTV#z`g-!PMvrQpl8KF?vuH7?!`kj|x zzfXD~Sx(k1k$o23!!V5-}0{)wn*>T7< zxf;l@(Z1>$iz$um@$#FGYoo$hc>){9m&;YoLOn83DIUhj3LEIIfkCIfDtJ##^`9N* z4Ach*zVr`35Ad*Y;BD>^H%5zGOyqHyLBY)r=Ve?n_QwpKcD^sj4uh%=MKZSGce?Ab zpu?#A*l2WS+T-5>gZ%b1&eFo(E^L0A$nUFo3mZYAaA>IPP4cJ8<5mMzH$VLPDqpqf z(E40~m(D}om`x-aQwqw&_8@*NEaA(x(|;G`dAAy^fYo9+RMwM`>sB|dH1}g*<*M%J zZ39=pkgpC={rP)xt85(iij|hI!VyKt1o{4B;U2k0MX1`VWY6fN!-a<^)oy+M9Kn3rvGFrATW4T@Y*67E6aBtcn3$YOTu3`->ryQ@@ey7<~ z+O6E))-6z!$+4*FOG|#&)%7#b@SZzU3S@MbDV8XKCD;1+bZt99xv{-zCH{(tuQuDTz=cU z%U-9^b;ZqPnOlD=2w!Ox_lMt6d!AOthdm|a%^Cgq`&MOcdUQ{*Pu$zHkutqpbgjv_ zY3z4ya_e!NfzHYBWW8ZKt3FE@3p={J(X&41aoE86t>GBc<6tZch?HDRIOf2+jpnlXn3FT$gRQJ zdgD{uIOpR{cD-$mdHrU;&o(y`t6gR)hmV|TbYFMuL3K6uH!RLJ z0xv=Z?d8dmPb7)8WR5V+0|O1Lme$q;Z;N-f9*-K3dEu-5{xh=FLYVWRjI;iFN$bCbzbysTm+riQ z3ByaPhV`E8>f2pvR)Tivk+7@vZt;g|S63#@G)KzkKTsaMtjG@fdLi=Wov45)$2cNx z1>}X?s&%Y7=oF$m*B317y7wUs*F2TD#Rm>u4khwmD;3RWIuzNCC5-Pyg2$00c&W_v zUPWisDO28B_pX1PU-aGOdyBf^m0Y%=_^H+_zPX{#$^G7;W(qXj(~$YX?xnPzD1L(B z3jdJi#?vnvUFW~=J+Tw`9E0rQR@RSyXf2ngp{KO;o^CQtk;k9Ow70(E6usJPPq1Eg z{~F%uzb}X`uB6z`XtJE|wSLA)r@tT;yK~OV{o;78uP?*SDdec&M~0nw{E-9SuAAOi z$tKEPEH$iP>H%6bzprn>^^&o_)|QAaM!uG^YYKc~7<6-ZQFJaS)gKx`q)uEQZt~`w z&uu;TIy%0pw@T6cyy|%^jXrpD9z-WdKW|fYcCJ&PxdBw@)l0pnkME4nMWV7%#u}clAD+eUqj72=4q6Qu}EP{a?uVu#Q|g-QP2Lu~W}2iXSLv z99t9fdNf|(KCydSm?_7{i%tlrPoX$h4E;jWd~Wg3S0nq_nscv56)jGEosh9vuSn5j zg){Str=(3G+vYQ z$HY84C-CrBMfPudm!<9Ae@^VYmQ5VFXp2MWhm>ihEB!;h6@`oh&b{n@`7$G;XXdL` z<94>dwaS#!fG6Y2x-KEypf!Q7p1s;wWbAl7xEa3UN3i7DP{&D~3v$S5FdTzdngnEg{6p79O2FU6pR{gH z{xkj}lYnFnqvLz`&pERnJ91(ph@o|&Ex3wrMq}dIvsX4U9O8eRkf1!zoQJrf+aZH(<1n{qAhb zv)}*Z@mT2T0nt@Yxq14Db07c19S($FO;?H*trGs}*LZ41)U$g{*#^dsh*J1SNgqC_ z@L5X_4`&m{9{mDE&on$XmKe%`&(>>nv5r&`#htF7vIkjNJ7dp$*GMsr5 zCNU97f>#0!D69>}>If%K>Ke?1)#e~|6*H^{46C-qrjCA%F2Z>0fVW{4 zhL8;3L8VI!(@%jHE=WaU(3ge&Y5U4XTC%z_AOg3nv=0P(p6PGu$`^XW>-6dxSt8Ol z+Bfcm^`3T}mrwl4W06)C8yEoL_CT$b~n{}07^R~Y~R diff --git a/third_party/test/golden_widget/flutter_logo.string.png b/third_party/test/golden_widget/flutter_logo.string.png index 8d8d2c65e9c990f9717bad016fa762604a2965d3..3047bb244977137bb504f2f6888400a95bd2cc8b 100644 GIT binary patch literal 10317 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 literal 11111 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 diff --git a/third_party/test/golden_widget/flutter_logo.string.rtl.png b/third_party/test/golden_widget/flutter_logo.string.rtl.png index faede873117038b4871e008ad0b37153085713e8..fa6dcf8e61d057420dd29568ae046d46861e48be 100644 GIT binary patch literal 10603 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 literal 11653 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 Date: Thu, 25 Oct 2018 11:13:12 -0700 Subject: [PATCH 160/512] uncomment example --- third_party/example/lib/main.dart | 66 +++++++++++++++---------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index 6e382342f0db..cae539f2a9a2 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -99,39 +99,39 @@ class _MyHomePageState extends State { ''')); - // for (String assetName in assetNames) { - // _painters.add( - // new SvgPicture.asset(assetName), - // ); - // } - - // for (int i = 0; i < iconNames.length; i++) { - // _painters.add( - // new Directionality( - // textDirection: TextDirection.ltr, - // child: new SvgPicture.asset( - // iconNames[i], - // color: Colors.blueGrey[(i + 1) * 100], - // matchTextDirection: true, - // ), - // ), - // ); - // } - - // // _painters.add(new SvgPicture.asset(iconNames[0], color: Colors.red)); - - // for (String uriName in uriNames) { - // _painters.add( - // new SvgPicture.network( - // uriName, - // placeholderBuilder: (BuildContext context) => new Container( - // padding: const EdgeInsets.all(30.0), - // child: const CircularProgressIndicator()), - // ), - // ); - // } - // _painters - // .add(new AvdPicture.asset('assets/android_vd/battery_charging.xml')); + for (String assetName in assetNames) { + _painters.add( + new SvgPicture.asset(assetName), + ); + } + + for (int i = 0; i < iconNames.length; i++) { + _painters.add( + new Directionality( + textDirection: TextDirection.ltr, + child: new SvgPicture.asset( + iconNames[i], + color: Colors.blueGrey[(i + 1) * 100], + matchTextDirection: true, + ), + ), + ); + } + + // _painters.add(new SvgPicture.asset(iconNames[0], color: Colors.red)); + + for (String uriName in uriNames) { + _painters.add( + new SvgPicture.network( + uriName, + placeholderBuilder: (BuildContext context) => new Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator()), + ), + ); + } + _painters + .add(new AvdPicture.asset('assets/android_vd/battery_charging.xml')); } @override From 998b9ca5bcbb646e2e14665584c04c0321a7422e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 3 Nov 2018 00:36:31 -0700 Subject: [PATCH 161/512] add coverage back --- third_party/.travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/.travis.yml b/third_party/.travis.yml index 94aa202001d7..bc9f40bee859 100644 --- a/third_party/.travis.yml +++ b/third_party/.travis.yml @@ -15,7 +15,7 @@ before_script: - gem install coveralls-lcov script: - ./flutter/bin/flutter analyze - - ./flutter/bin/flutter test + - ./flutter/bin/flutter test --coverage after_success: - coveralls-lcov coverage/lcov.info cache: From 942d5977a8ba0655dba52630de3c93213546d44d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 3 Nov 2018 00:41:50 -0700 Subject: [PATCH 162/512] remove deprecated analyzer portion, bump path_drawing --- third_party/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 3eb4966b3a59..7ebf0a841085 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/dnfield/flutter_svg version: 0.6.2 dependencies: - path_drawing: ^0.3.1 + path_drawing: ^0.4.0 xml: ^3.0.0 vector_math: ^2.0.4 meta: ^1.1.2 From 154281e79e35e266913ca66d1abdf1a5e46f33b1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 4 Nov 2018 19:55:51 -0800 Subject: [PATCH 163/512] fix fill-rule, bump path_drawing --- third_party/CHANGELOG.md | 5 +++++ .../example/assets/simple/fill-rule-inherit.svg | 4 ++++ third_party/example/lib/main.dart | 13 +------------ third_party/example/pubspec.lock | 4 ++-- third_party/golden/simple/fill-rule-inherit.png | Bin 0 -> 5300 bytes third_party/lib/src/svg_parser.dart | 6 +++++- third_party/pubspec.lock | 2 +- third_party/pubspec.yaml | 2 +- 8 files changed, 19 insertions(+), 17 deletions(-) create mode 100644 third_party/example/assets/simple/fill-rule-inherit.svg create mode 100644 third_party/golden/simple/fill-rule-inherit.png diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index e7fb9ffa0062..4607fb57d22b 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 0.6.3 + +- Consume updated fversion of path_drawing. +- Fix bug with fill-rule inheritence + example to test. + ## 0.6.2 - Consume updated version of path_drawing, which fixes https://github.com/dnfield/flutter_svg/issues/73 diff --git a/third_party/example/assets/simple/fill-rule-inherit.svg b/third_party/example/assets/simple/fill-rule-inherit.svg new file mode 100644 index 000000000000..cedebd1a5c4e --- /dev/null +++ b/third_party/example/assets/simple/fill-rule-inherit.svg @@ -0,0 +1,4 @@ + + + \ No newline at end of file diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index cae539f2a9a2..65363f54f8de 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -12,6 +12,7 @@ const List assetNames = const [ 'assets/simple/clip_path_3.svg', 'assets/simple/clip_path_2.svg', 'assets/simple/clip_path.svg', + 'assets/simple/fill-rule-inherit.svg', 'assets/simple/group_fill_opacity.svg', 'assets/simple/group_opacity.svg', 'assets/simple/text.svg', @@ -87,18 +88,6 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; - _painters.add(SvgPicture.string(''' - - ic_checked - - - - - - -''')); - for (String assetName in assetNames) { _painters.add( new SvgPicture.asset(assetName), diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index f2739a08e591..43e439dbeb91 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.6.2" + version: "0.6.3" meta: dependency: transitive description: @@ -33,7 +33,7 @@ packages: name: path_drawing url: "https://pub.dartlang.org" source: hosted - version: "0.3.1" + version: "0.4.0" path_parsing: dependency: transitive description: diff --git a/third_party/golden/simple/fill-rule-inherit.png b/third_party/golden/simple/fill-rule-inherit.png new file mode 100644 index 0000000000000000000000000000000000000000..7755de05be13f5f8d7a4994941b3a14a7c171d6a GIT binary patch literal 5300 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 homepage: https://github.com/dnfield/flutter_svg -version: 0.6.2 +version: 0.6.3 dependencies: path_drawing: ^0.4.0 From 10ac30f4da1a2567d64741511bf9659798194787 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 4 Nov 2018 22:21:15 -0800 Subject: [PATCH 164/512] Correct width/height processing, update lints --- third_party/CHANGELOG.md | 12 +- .../example/assets/simple/clip_path.svg | 2 +- .../example/assets/simple/clip_path_2.svg | 2 +- .../example/assets/simple/clip_path_3.svg | 2 +- .../example/assets/simple/dash_path.svg | 2 +- third_party/example/assets/simple/ellipse.svg | 2 +- .../assets/simple/group_fill_opacity.svg | 2 +- .../example/assets/simple/group_opacity.svg | 2 +- .../example/assets/simple/linear_gradient.svg | 2 +- .../assets/simple/linear_gradient_2.svg | 2 +- ...gradient_absolute_user_space_translate.svg | 2 +- ...gradient_percentage_bounding_translate.svg | 2 +- ...adient_percentage_user_space_translate.svg | 2 +- third_party/example/assets/simple/male.svg | 12 +- .../example/assets/simple/nested_group.svg | 2 +- .../example/assets/simple/opacity_on_path.svg | 3 +- .../example/assets/simple/radial_gradient.svg | 13 +- ...gradient_absolute_user_space_translate.svg | 17 +- ...gradient_percentage_bounding_translate.svg | 17 +- ...adient_percentage_user_space_translate.svg | 17 +- .../example/assets/simple/rect_rrect.svg | 2 +- .../assets/simple/rect_rrect_no_ry.svg | 2 +- .../assets/simple/stroke_inherit_circles.svg | 3 +- .../assets/simple/width_height_viewbox.svg | 15 + .../example/assets/wikimedia/chess_knight.svg | 2 +- third_party/example/lib/main.dart | 45 ++- third_party/example/pubspec.lock | 2 +- .../golden/simple/width_height_viewbox.png | Bin 0 -> 1063 bytes third_party/lib/avd.dart | 36 +-- third_party/lib/src/avd/xml_parsers.dart | 13 +- third_party/lib/src/avd_parser.dart | 12 +- third_party/lib/src/picture_provider.dart | 53 ++- third_party/lib/src/picture_stream.dart | 35 +- third_party/lib/src/render_picture.dart | 14 +- third_party/lib/src/svg/colors.dart | 306 +++++++++--------- third_party/lib/src/svg/parsers.dart | 20 +- third_party/lib/src/svg/xml_parsers.dart | 165 ++++++---- third_party/lib/src/svg_parser.dart | 44 ++- third_party/lib/src/vector_drawable.dart | 111 ++++--- third_party/lib/svg.dart | 57 ++-- third_party/pubspec.yaml | 2 +- third_party/test/colors_svg_test.dart | 4 +- third_party/test/golden_svg_test.dart | 4 +- third_party/test/parser_svg_test.dart | 20 +- third_party/test/widget_svg_test.dart | 66 ++-- third_party/test/xml_svg_test.dart | 16 +- third_party/tool/gen_golden.dart | 20 +- 47 files changed, 630 insertions(+), 556 deletions(-) create mode 100644 third_party/example/assets/simple/width_height_viewbox.svg create mode 100644 third_party/golden/simple/width_height_viewbox.png diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 4607fb57d22b..2f74808e5136 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,8 +1,18 @@ # CHANGES +## 0.7.0 + +- **BREAKING** Correct erroneous `width` and `height` processing on the root element. + - Previously, `width` and `height` were treated as synonyms for the width and height of the `viewBox`. + This is not correct, and resulted in meaningful rendering errors in some scenarios compared to + Chrome. Fixing this makes the parser more conformant to the spec, but may make your SVGs look significantly + different if they specify `width` or `height`. + If you want the old behavior, you'll have to update your SVGs to not specify `width` and `height` (only + specify `viewBox`). + ## 0.6.3 -- Consume updated fversion of path_drawing. +- Consume updated version of path_drawing. - Fix bug with fill-rule inheritence + example to test. ## 0.6.2 diff --git a/third_party/example/assets/simple/clip_path.svg b/third_party/example/assets/simple/clip_path.svg index d0877e91a4ff..214d353b44f1 100644 --- a/third_party/example/assets/simple/clip_path.svg +++ b/third_party/example/assets/simple/clip_path.svg @@ -1,5 +1,5 @@ - + diff --git a/third_party/example/assets/simple/clip_path_2.svg b/third_party/example/assets/simple/clip_path_2.svg index a9707d923da3..41e60b68933c 100644 --- a/third_party/example/assets/simple/clip_path_2.svg +++ b/third_party/example/assets/simple/clip_path_2.svg @@ -1,4 +1,4 @@ - + diff --git a/third_party/example/assets/simple/clip_path_3.svg b/third_party/example/assets/simple/clip_path_3.svg index aae181a1e7dc..f97bd76e3dee 100644 --- a/third_party/example/assets/simple/clip_path_3.svg +++ b/third_party/example/assets/simple/clip_path_3.svg @@ -1,5 +1,5 @@ - + diff --git a/third_party/example/assets/simple/dash_path.svg b/third_party/example/assets/simple/dash_path.svg index cbd5fa9a4b85..70f58f828251 100644 --- a/third_party/example/assets/simple/dash_path.svg +++ b/third_party/example/assets/simple/dash_path.svg @@ -1,4 +1,4 @@ - + diff --git a/third_party/example/assets/simple/ellipse.svg b/third_party/example/assets/simple/ellipse.svg index 2ea45661cf0d..2ad80bdac7b5 100644 --- a/third_party/example/assets/simple/ellipse.svg +++ b/third_party/example/assets/simple/ellipse.svg @@ -1,4 +1,4 @@ - diff --git a/third_party/example/assets/simple/group_fill_opacity.svg b/third_party/example/assets/simple/group_fill_opacity.svg index 7a8e04f6604c..44216e06c1c3 100644 --- a/third_party/example/assets/simple/group_fill_opacity.svg +++ b/third_party/example/assets/simple/group_fill_opacity.svg @@ -1,6 +1,6 @@ - + diff --git a/third_party/example/assets/simple/group_opacity.svg b/third_party/example/assets/simple/group_opacity.svg index 1bc0a7a7f548..85e75db327fb 100644 --- a/third_party/example/assets/simple/group_opacity.svg +++ b/third_party/example/assets/simple/group_opacity.svg @@ -1,7 +1,7 @@ - Example opacity01 - opacity property diff --git a/third_party/example/assets/simple/linear_gradient.svg b/third_party/example/assets/simple/linear_gradient.svg index c0d45cdc5094..6dc63d5ce6e6 100644 --- a/third_party/example/assets/simple/linear_gradient.svg +++ b/third_party/example/assets/simple/linear_gradient.svg @@ -1,4 +1,4 @@ - + diff --git a/third_party/example/assets/simple/linear_gradient_2.svg b/third_party/example/assets/simple/linear_gradient_2.svg index eb75d36c2646..54c92ead9c37 100644 --- a/third_party/example/assets/simple/linear_gradient_2.svg +++ b/third_party/example/assets/simple/linear_gradient_2.svg @@ -1,7 +1,7 @@ - Example lingrad01 - fill a rectangle using a linear gradient paint server diff --git a/third_party/example/assets/simple/linear_gradient_absolute_user_space_translate.svg b/third_party/example/assets/simple/linear_gradient_absolute_user_space_translate.svg index ced5251b3e65..14245d72b257 100644 --- a/third_party/example/assets/simple/linear_gradient_absolute_user_space_translate.svg +++ b/third_party/example/assets/simple/linear_gradient_absolute_user_space_translate.svg @@ -1,4 +1,4 @@ - + diff --git a/third_party/example/assets/simple/linear_gradient_percentage_bounding_translate.svg b/third_party/example/assets/simple/linear_gradient_percentage_bounding_translate.svg index be1ef28c5502..272eae3fb1db 100644 --- a/third_party/example/assets/simple/linear_gradient_percentage_bounding_translate.svg +++ b/third_party/example/assets/simple/linear_gradient_percentage_bounding_translate.svg @@ -1,4 +1,4 @@ - + diff --git a/third_party/example/assets/simple/linear_gradient_percentage_user_space_translate.svg b/third_party/example/assets/simple/linear_gradient_percentage_user_space_translate.svg index c2b0ce07ffb1..cd8a97a8e2f1 100644 --- a/third_party/example/assets/simple/linear_gradient_percentage_user_space_translate.svg +++ b/third_party/example/assets/simple/linear_gradient_percentage_user_space_translate.svg @@ -1,4 +1,4 @@ - + diff --git a/third_party/example/assets/simple/male.svg b/third_party/example/assets/simple/male.svg index 208973591db7..5dc9f18ff316 100644 --- a/third_party/example/assets/simple/male.svg +++ b/third_party/example/assets/simple/male.svg @@ -1,2 +1,12 @@ - \ No newline at end of file + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/nested_group.svg b/third_party/example/assets/simple/nested_group.svg index 6f8472319a67..e0677f87089e 100644 --- a/third_party/example/assets/simple/nested_group.svg +++ b/third_party/example/assets/simple/nested_group.svg @@ -1,4 +1,4 @@ - diff --git a/third_party/example/assets/simple/opacity_on_path.svg b/third_party/example/assets/simple/opacity_on_path.svg index 9f870d066e21..481dd35233f8 100644 --- a/third_party/example/assets/simple/opacity_on_path.svg +++ b/third_party/example/assets/simple/opacity_on_path.svg @@ -1,3 +1,4 @@ - + diff --git a/third_party/example/assets/simple/radial_gradient.svg b/third_party/example/assets/simple/radial_gradient.svg index 42bcbd6e9038..be8c6bca2a6a 100644 --- a/third_party/example/assets/simple/radial_gradient.svg +++ b/third_party/example/assets/simple/radial_gradient.svg @@ -1,14 +1,13 @@ - + Example radgrad01 - fill a rectangle by referencing a radial gradient paint server - + @@ -16,11 +15,9 @@ - + - + \ No newline at end of file diff --git a/third_party/example/assets/simple/radial_gradient_absolute_user_space_translate.svg b/third_party/example/assets/simple/radial_gradient_absolute_user_space_translate.svg index 4268fea810d2..9b31aaa99d41 100644 --- a/third_party/example/assets/simple/radial_gradient_absolute_user_space_translate.svg +++ b/third_party/example/assets/simple/radial_gradient_absolute_user_space_translate.svg @@ -1,9 +1,10 @@ - - - - - - - - + + + + + + + + diff --git a/third_party/example/assets/simple/radial_gradient_percentage_bounding_translate.svg b/third_party/example/assets/simple/radial_gradient_percentage_bounding_translate.svg index 3fd58495c8b6..91279aa96eb1 100644 --- a/third_party/example/assets/simple/radial_gradient_percentage_bounding_translate.svg +++ b/third_party/example/assets/simple/radial_gradient_percentage_bounding_translate.svg @@ -1,9 +1,10 @@ - - - - - - - - + + + + + + + + diff --git a/third_party/example/assets/simple/radial_gradient_percentage_user_space_translate.svg b/third_party/example/assets/simple/radial_gradient_percentage_user_space_translate.svg index 303ff7d27ae3..7d8827bc4036 100644 --- a/third_party/example/assets/simple/radial_gradient_percentage_user_space_translate.svg +++ b/third_party/example/assets/simple/radial_gradient_percentage_user_space_translate.svg @@ -1,9 +1,10 @@ - - - - - - - - + + + + + + + + diff --git a/third_party/example/assets/simple/rect_rrect.svg b/third_party/example/assets/simple/rect_rrect.svg index 5960d185df26..24ce5bcbb0eb 100644 --- a/third_party/example/assets/simple/rect_rrect.svg +++ b/third_party/example/assets/simple/rect_rrect.svg @@ -1,4 +1,4 @@ - + diff --git a/third_party/example/assets/simple/rect_rrect_no_ry.svg b/third_party/example/assets/simple/rect_rrect_no_ry.svg index b98dd11995ca..59734736b771 100644 --- a/third_party/example/assets/simple/rect_rrect_no_ry.svg +++ b/third_party/example/assets/simple/rect_rrect_no_ry.svg @@ -1,3 +1,3 @@ - + diff --git a/third_party/example/assets/simple/stroke_inherit_circles.svg b/third_party/example/assets/simple/stroke_inherit_circles.svg index da6e78f73ea1..804bfad35d6d 100644 --- a/third_party/example/assets/simple/stroke_inherit_circles.svg +++ b/third_party/example/assets/simple/stroke_inherit_circles.svg @@ -1,4 +1,5 @@ - + diff --git a/third_party/example/assets/simple/width_height_viewbox.svg b/third_party/example/assets/simple/width_height_viewbox.svg new file mode 100644 index 000000000000..99658b912dc3 --- /dev/null +++ b/third_party/example/assets/simple/width_height_viewbox.svg @@ -0,0 +1,15 @@ + + + Close + Created with Sketch. + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/assets/wikimedia/chess_knight.svg b/third_party/example/assets/wikimedia/chess_knight.svg index eabd2af51a23..72b429e0b060 100644 --- a/third_party/example/assets/wikimedia/chess_knight.svg +++ b/third_party/example/assets/wikimedia/chess_knight.svg @@ -1,6 +1,6 @@ - + assetNames = const [ +const List assetNames = [ // // 'assets/notfound.svg', 'assets/flutter_logo.svg', 'assets/dart.svg', @@ -34,7 +34,7 @@ const List assetNames = const [ 'assets/wikimedia/Firefox_Logo_2017.svg', ]; -const List iconNames = const [ +const List iconNames = [ 'assets/deborah_ufw/new-action-expander.svg', 'assets/deborah_ufw/new-camera.svg', 'assets/deborah_ufw/new-gif-button.svg', @@ -47,23 +47,23 @@ const List iconNames = const [ 'assets/deborah_ufw/numeric_25.svg', ]; -const List uriNames = const [ +const List uriNames = [ 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', ]; void main() { - runApp(new MyApp()); + runApp(MyApp()); } class MyApp extends StatelessWidget { // This widget is the root of your application. @override Widget build(BuildContext context) { - return new MaterialApp( + return MaterialApp( title: 'Flutter Demo', - theme: new ThemeData( + theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Flutter SVG Demo'), @@ -76,7 +76,7 @@ class MyHomePage extends StatefulWidget { final String title; @override - _MyHomePageState createState() => new _MyHomePageState(); + _MyHomePageState createState() => _MyHomePageState(); } class _MyHomePageState extends State { @@ -90,15 +90,15 @@ class _MyHomePageState extends State { for (String assetName in assetNames) { _painters.add( - new SvgPicture.asset(assetName), + SvgPicture.asset(assetName), ); } for (int i = 0; i < iconNames.length; i++) { _painters.add( - new Directionality( + Directionality( textDirection: TextDirection.ltr, - child: new SvgPicture.asset( + child: SvgPicture.asset( iconNames[i], color: Colors.blueGrey[(i + 1) * 100], matchTextDirection: true, @@ -111,16 +111,15 @@ class _MyHomePageState extends State { for (String uriName in uriNames) { _painters.add( - new SvgPicture.network( + SvgPicture.network( uriName, - placeholderBuilder: (BuildContext context) => new Container( + placeholderBuilder: (BuildContext context) => Container( padding: const EdgeInsets.all(30.0), child: const CircularProgressIndicator()), ), ); } - _painters - .add(new AvdPicture.asset('assets/android_vd/battery_charging.xml')); + _painters.add(AvdPicture.asset('assets/android_vd/battery_charging.xml')); } @override @@ -128,26 +127,26 @@ class _MyHomePageState extends State { if (_dimension > MediaQuery.of(context).size.width - 10.0) { _dimension = MediaQuery.of(context).size.width - 10.0; } - return new Scaffold( - appBar: new AppBar( - title: new Text(widget.title), + return Scaffold( + appBar: AppBar( + title: Text(widget.title), ), - body: new Column(children: [ - new Slider( + body: Column(children: [ + Slider( min: 5.0, max: MediaQuery.of(context).size.width - 10.0, value: _dimension, onChanged: (double val) { setState(() => _dimension = val); }), - // new FlutterLogo(size: _dimension), - // new Container( + // FlutterLogo(size: _dimension), + // Container( // padding: const EdgeInsets.all(12.0), // child: // ) - new Expanded( - child: new GridView.extent( + Expanded( + child: GridView.extent( shrinkWrap: true, maxCrossAxisExtent: _dimension, padding: const EdgeInsets.all(4.0), diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index 43e439dbeb91..f5d2001ff557 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.6.3" + version: "0.7.0" meta: dependency: transitive description: diff --git a/third_party/golden/simple/width_height_viewbox.png b/third_party/golden/simple/width_height_viewbox.png new file mode 100644 index 0000000000000000000000000000000000000000..d82895c0d2283d746e3613568f6aed2436d5181c GIT binary patch literal 1063 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_tJfo-U3d6?5L+J?s0}N8-T8lUeI8aHKoT35#a7C{+@;$d)clX)P+n9d%eR;Y~`%mroZ_Zvob4dm9N0av7|39NzIAGP$y8ZXh@8#6E zx_zfPgQ_sc76BOI;9Qb9t0Q%R#bV~0Z_8f(`ek*sRCeS1d)HoZZ5ck$+%K4rQ4+77N)*nh0>!_NcHzWj_TjjdKy zytBaJpUClpA`}0-l~PiSdhc-Sk;MtglN-0XIxUH7Ea`l#;I0yTU4%2xiv5y$U-Jo% zU+YwbluEc#JY?7fC-THPtMrtbOfW2z>FG?#Nl;4cx#pns$U>s%!s2_2I$IV-F|T}W z^~G$G9lPBx=epSIFaQ3v&9U9rcFjRfPA(`kbfNg0q7TJ2%-e3}TsnK!_r$B~0mHl2MIt0T5^ zTHDDK&XjW-?FBS#CRnl`cieKp;hBsrmt_m9(eXx6&Yi6+M$a8ZIW2qnmb5TO9g?%~ zUCgBUGGW>lalhja9K38MsJ`p0zrDc0%dSK9eQ&-0dxs*K1E)`)zVOw>X-Zt<6RESG zzkM@1&EjsctXN^^^DtlAgMzzWh@1#}=IC|8zsACu|e1hUc7ruxW z(w!C^7hX^QVmI;047*FFLWKfLzweERRXS-o>v;q)a4#*`U3pt+W>VhO`@n#_2n_R2 z%RQFKy!vJd4Bx{G>JNTfeK&7 avdPictureStringDecoder(String raw, bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter, String key) { final DrawableRoot svg = fromAvdString(raw, key); - return new PictureInfo( + return PictureInfo( picture: svg.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter), - viewBox: svg.viewport.rect); + viewport: svg.viewport.viewBoxRect); } FutureOr fromAvdBytes(Uint8List raw, String key) async { @@ -65,15 +65,11 @@ class Avd { final XmlElement svg = xml.parse(rawSvg).rootElement; final DrawableViewport viewBox = parseViewBox(svg); final List children = svg.children - .where((XmlNode child) => child is XmlElement) - .map((XmlNode child) => parseAvdElement( - child, - new Rect.fromPoints( - Offset.zero, new Offset(viewBox.width, viewBox.height)))) + .whereType() + .map((XmlElement child) => parseAvdElement(child, viewBox.viewBoxRect)) .toList(); // todo : style on root - return new DrawableRoot( - viewBox, children, new DrawableDefinitionServer(), null); + return DrawableRoot(viewBox, children, DrawableDefinitionServer(), null); } } @@ -98,7 +94,7 @@ class AvdPicture extends SvgPicture { BlendMode colorBlendMode = BlendMode.srcIn, Key key}) : this( - new StringPicture( + StringPicture( allowDrawingOutsideViewBox == true ? avdStringDecoderOutsideViewBox : avdStringDecoder, @@ -119,7 +115,7 @@ class AvdPicture extends SvgPicture { Color color, BlendMode colorBlendMode = BlendMode.srcIn}) : this( - new ExactAssetPicture( + ExactAssetPicture( allowDrawingOutsideViewBox == true ? avdByteDecoderOutsideViewBox : avdByteDecoder, @@ -135,7 +131,7 @@ class AvdPicture extends SvgPicture { static ColorFilter _getColorFilter(Color color, BlendMode colorBlendMode) => color == null ? null - : new ColorFilter.mode(color, colorBlendMode ?? BlendMode.srcIn); + : ColorFilter.mode(color, colorBlendMode ?? BlendMode.srcIn); static final PictureInfoDecoder avdByteDecoder = (Uint8List bytes, ColorFilter colorFilter, String key) => @@ -152,17 +148,13 @@ class AvdPicture extends SvgPicture { } /// Creates a [DrawableRoot] from a string of SVG data. -DrawableRoot fromAvdString(String rawSvg, Size size) { +DrawableRoot fromAvdString(String rawSvg, Rect size) { final XmlElement svg = xml.parse(rawSvg).rootElement; final DrawableViewport viewBox = parseViewBox(svg); final List children = svg.children - .where((XmlNode child) => child is XmlElement) - .map((XmlNode child) => parseAvdElement( - child, - new Rect.fromPoints( - Offset.zero, new Offset(size.width, size.height)))) + .whereType() + .map((XmlElement child) => parseAvdElement(child, size)) .toList(); // todo : style on root - return new DrawableRoot( - viewBox, children, new DrawableDefinitionServer(), null); + return DrawableRoot(viewBox, children, DrawableDefinitionServer(), null); } diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index f397ef173f4e..ded962ac1044 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -17,11 +17,14 @@ DrawableViewport parseViewBox(XmlElement el) { final String rawHeight = getAttribute(el, 'viewportHeight', def: '', namespace: androidNS); if (rawWidth == '' || rawHeight == '') { - return new DrawableViewport(Rect.zero); + return const DrawableViewport(Size.zero, Size.zero); } final double width = double.parse(rawWidth); final double height = double.parse(rawHeight); - return new DrawableViewport(Rect.fromLTWH(0.0, 0.0, width, height)); + return DrawableViewport( + Size(width, height), + Size(width, height), + ); } Matrix4 parseTransform(XmlElement el) { @@ -40,7 +43,7 @@ Matrix4 parseTransform(XmlElement el) { final double translateY = double.parse( getAttribute(el, 'translateY', def: '0', namespace: androidNS)); - return new Matrix4.identity() + return Matrix4.identity() ..translate(pivotX, pivotY) ..rotateZ(rotation * pi / 180) ..scale(scaleX, scaleY) @@ -53,7 +56,7 @@ DrawablePaint parseStroke(XmlElement el, Rect bounds) { if (rawStroke == null) { return null; } - return new DrawablePaint( + return DrawablePaint( PaintingStyle.stroke, color: parseColor(rawStroke).withOpacity(double.parse( getAttribute(el, 'strokeAlpha', def: '1', namespace: androidNS))), @@ -106,7 +109,7 @@ DrawablePaint parseFill(XmlElement el, Rect bounds) { if (rawFill == null) { return null; } - return new DrawablePaint( + return DrawablePaint( PaintingStyle.fill, color: parseColor(rawFill) .withOpacity(double.parse(getAttribute(el, 'fillAlpha', def: '1'))), diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index 7c4281bcfaa5..ba3d6ce29c36 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -29,9 +29,9 @@ class DrawableAvdPath extends DrawableShape { final DrawablePaint stroke = parseStroke(el, path.getBounds()); final DrawablePaint fill = parseFill(el, path.getBounds()); - return new DrawableAvdPath( + return DrawableAvdPath( path, - new DrawableStyle(stroke: stroke, fill: fill), + DrawableStyle(stroke: stroke, fill: fill), ); } } @@ -41,13 +41,13 @@ class DrawableAvdPath extends DrawableShape { /// If an unsupported element is encountered, it will be created as a [DrawableNoop]. Drawable parseAvdElement(XmlElement el, Rect bounds) { if (el.name.local == 'path') { - return new DrawableAvdPath.fromXml(el); + return DrawableAvdPath.fromXml(el); } else if (el.name.local == 'group') { return parseAvdGroup(el, bounds); } // TODO: clipPath print('Unhandled element ${el.name.local}'); - return new DrawableNoop(el.name.local); + return DrawableNoop(el.name.local); } /// Parses an AVD element. @@ -67,9 +67,9 @@ Drawable parseAvdGroup(XmlElement el, Rect bounds) { final DrawablePaint fill = parseFill(el, bounds); final DrawablePaint stroke = parseStroke(el, bounds); - return new DrawableGroup( + return DrawableGroup( children, - new DrawableStyle( + DrawableStyle( transform: transform?.storage, stroke: stroke, fill: fill, diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 29f987f2c989..f47f85a5fa79 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -16,7 +16,7 @@ import 'package:flutter/widgets.dart' import 'picture_cache.dart'; import 'picture_stream.dart'; -typedef FutureOr PictureInfoDecoder( +typedef PictureInfoDecoder = FutureOr Function( T data, ColorFilter colorFilter, String key); /// Creates an [PictureConfiguration] based on the given [BuildContext] (and @@ -34,7 +34,7 @@ typedef FutureOr PictureInfoDecoder( /// * [PictureProvider], which has an example showing how this might be used. PictureConfiguration createLocalPictureConfiguration(BuildContext context, {Rect viewBox, Color color, BlendMode colorBlendMode}) { - return new PictureConfiguration( + return PictureConfiguration( bundle: DefaultAssetBundle.of(context), locale: Localizations.localeOf(context, nullOk: true), textDirection: Directionality.of(context), @@ -80,7 +80,7 @@ class PictureConfiguration { String platform, ColorFilter colorFilter, }) { - return new PictureConfiguration( + return PictureConfiguration( bundle: bundle ?? this.bundle, locale: locale ?? this.locale, textDirection: textDirection ?? this.textDirection, @@ -115,7 +115,7 @@ class PictureConfiguration { /// a picture configuration that provides no additional information. /// /// Useful when resolving an [PictureProvider] without any context. - static const PictureConfiguration empty = const PictureConfiguration(); + static const PictureConfiguration empty = PictureConfiguration(); @override bool operator ==(dynamic other) { @@ -137,7 +137,7 @@ class PictureConfiguration { @override String toString() { - final StringBuffer result = new StringBuffer(); + final StringBuffer result = StringBuffer(); result.write('PictureConfiguration('); bool hasArguments = false; if (bundle != null) { @@ -188,7 +188,7 @@ class PictureConfiguration { } // TODO: allow other people to implement this. -PictureCache _cache = new PictureCache(); +PictureCache _cache = PictureCache(); /// Identifies a picture without committing to the precise final asset. This /// allows a set of pictures to be identified and for the precise picture to later @@ -227,7 +227,7 @@ PictureCache _cache = new PictureCache(); /// final PictureProvider PictureProvider; /// /// @override -/// _MyPictureState createState() => new _MyPictureState(); +/// _MyPictureState createState() => _MyPictureState(); /// } /// /// class _MyPictureState extends State { @@ -277,7 +277,7 @@ PictureCache _cache = new PictureCache(); /// /// @override /// Widget build(BuildContext context) { -/// return new RawPicture( +/// return RawPicture( /// picture: _pictureInfo?.picture, // this is a dart:ui Picture object /// scale: _pictureInfo?.scale ?? 1.0, /// ); @@ -299,13 +299,13 @@ abstract class PictureProvider { /// method. PictureStream resolve(PictureConfiguration picture) { // assert(picture != null); - final PictureStream stream = new PictureStream(); + final PictureStream stream = PictureStream(); T obtainedKey; obtainKey().then((T key) { obtainedKey = key; stream.setCompleter(_cache.putIfAbsent(key, () => load(key))); }).catchError((dynamic exception, StackTrace stack) async { - FlutterError.reportError(new FlutterErrorDetails( + FlutterError.reportError(FlutterErrorDetails( exception: exception, stack: stack, library: 'services library', @@ -403,7 +403,7 @@ abstract class AssetBundlePictureProvider /// picture using [_loadAsync]. @override PictureStreamCompleter load(AssetBundlePictureKey key) { - return new OneFramePictureStreamCompleter(_loadAsync(key), + return OneFramePictureStreamCompleter(_loadAsync(key), informationCollector: (StringBuffer information) { information.writeln('Picture provider: $this'); information.write('Picture key: $key'); @@ -426,7 +426,7 @@ abstract class AssetBundlePictureProvider } } -final HttpClient _httpClient = new HttpClient(); +final HttpClient _httpClient = HttpClient(); /// Fetches the given URL from the network, associating it with the given scale. /// @@ -458,12 +458,12 @@ class NetworkPicture extends PictureProvider { @override Future obtainKey() { - return new SynchronousFuture(this); + return SynchronousFuture(this); } @override PictureStreamCompleter load(NetworkPicture key) { - return new OneFramePictureStreamCompleter(_loadAsync(key), + return OneFramePictureStreamCompleter(_loadAsync(key), informationCollector: (StringBuffer information) { information.writeln('Picture provider: $this'); information.write('Picture key: $key'); @@ -482,7 +482,7 @@ class NetworkPicture extends PictureProvider { final HttpClientResponse response = await request.close(); if (response.statusCode != HttpStatus.ok) { - throw new HttpException('Could not get network asset', uri: uri); + throw HttpException('Could not get network asset', uri: uri); } final Uint8List bytes = await consolidateHttpClientResponseBytes(response); @@ -531,12 +531,12 @@ class FilePicture extends PictureProvider { @override Future obtainKey() { - return new SynchronousFuture(this); + return SynchronousFuture(this); } @override PictureStreamCompleter load(FilePicture key) { - return new OneFramePictureStreamCompleter(_loadAsync(key), + return OneFramePictureStreamCompleter(_loadAsync(key), informationCollector: (StringBuffer information) { information.writeln('Path: ${file?.path}'); }); @@ -601,12 +601,12 @@ class MemoryPicture extends PictureProvider { @override Future obtainKey() { - return new SynchronousFuture(this); + return SynchronousFuture(this); } @override PictureStreamCompleter load(MemoryPicture key) { - return new OneFramePictureStreamCompleter(_loadAsync(key)); + return OneFramePictureStreamCompleter(_loadAsync(key)); } Future _loadAsync(MemoryPicture key) async { @@ -648,12 +648,12 @@ class StringPicture extends PictureProvider { @override Future obtainKey() { - return new SynchronousFuture(this); + return SynchronousFuture(this); } @override PictureStreamCompleter load(StringPicture key) { - return new OneFramePictureStreamCompleter(_loadAsync(key)); + return OneFramePictureStreamCompleter(_loadAsync(key)); } Future _loadAsync(StringPicture key) async { @@ -702,7 +702,7 @@ class StringPicture extends PictureProvider { /// Then, to fetch the picture and associate it with scale `1.5`, use /// /// ```dart -/// new AssetPicture('icons/heart.png', scale: 1.5) +/// AssetPicture('icons/heart.png', scale: 1.5) /// ``` /// ///## Assets in packages @@ -712,7 +712,7 @@ class StringPicture extends PictureProvider { /// `my_icons`. Then to fetch the picture, use: /// /// ```dart -/// new AssetPicture('icons/heart.png', scale: 1.5, package: 'my_icons') +/// AssetPicture('icons/heart.png', scale: 1.5, package: 'my_icons') /// ``` /// /// Assets used by the package itself should also be fetched using the [package] @@ -795,11 +795,8 @@ class ExactAssetPicture extends AssetBundlePictureProvider { @override Future obtainKey() { - return new SynchronousFuture( - new AssetBundlePictureKey( - bundle: bundle ?? rootBundle, - name: keyName, - colorFilter: colorFilter)); + return SynchronousFuture(AssetBundlePictureKey( + bundle: bundle ?? rootBundle, name: keyName, colorFilter: colorFilter)); } @override diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart index a922ed6ee6f3..5eb6e0eb7f98 100644 --- a/third_party/lib/src/picture_stream.dart +++ b/third_party/lib/src/picture_stream.dart @@ -7,25 +7,28 @@ import 'dart:ui' show Picture, Rect, hashValues; import 'package:flutter/foundation.dart'; +/// Represents information about a ui.Picture to be drawn on a canvas. @immutable class PictureInfo { - const PictureInfo({@required this.picture, @required this.viewBox}) - : assert(picture != null), - assert(viewBox != null); + const PictureInfo({ + @required this.picture, + @required this.viewport, + }) : assert(picture != null), + assert(viewport != null); /// The raw picture. /// /// This is the object to pass to the [Canvas.drawPicture] when painting. final Picture picture; - /// The viewBox enclosing the coordinates used in the picture. - final Rect viewBox; + /// The viewport enclosing the coordinates used in the picture. + final Rect viewport; @override - String toString() => '$picture $viewBox'; + String toString() => '$picture $viewport'; @override - int get hashCode => hashValues(picture, viewBox); + int get hashCode => hashValues(picture, viewport); @override bool operator ==(Object other) { @@ -33,7 +36,7 @@ class PictureInfo { return false; } final PictureInfo typedOther = other; - return typedOther.picture == picture && typedOther.viewBox == viewBox; + return typedOther.picture == picture && typedOther.viewport == viewport; } } @@ -47,7 +50,7 @@ class PictureInfo { /// frame is requested if the call was asynchronous (after the current frame) /// and no rendering frame is requested if the call was synchronous (within the /// same stack frame as the call to [PictureStream.addListener]). -typedef void PictureListener(PictureInfo image, bool synchronousCall); +typedef PictureListener = Function(PictureInfo image, bool synchronousCall); /// A handle to an image resource. /// @@ -141,13 +144,13 @@ class PictureStream extends Diagnosticable { @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); - properties.add(new ObjectFlagProperty( + properties.add(ObjectFlagProperty( 'completer', _completer, ifPresent: _completer?.toStringShort(), ifNull: 'unresolved', )); - properties.add(new ObjectFlagProperty>( + properties.add(ObjectFlagProperty>( 'listeners', _listeners, ifPresent: @@ -205,7 +208,7 @@ abstract class PictureStreamCompleter extends Diagnosticable { return; } final List localListeners = - new List.from(_listeners); + List.from(_listeners); for (PictureListener listener in localListeners) { try { listener(image, false); @@ -216,7 +219,7 @@ abstract class PictureStreamCompleter extends Diagnosticable { } void _handleImageError(String context, dynamic exception, dynamic stack) { - FlutterError.reportError(new FlutterErrorDetails( + FlutterError.reportError(FlutterErrorDetails( exception: exception, stack: stack, library: 'image resource service', @@ -228,9 +231,9 @@ abstract class PictureStreamCompleter extends Diagnosticable { @override void debugFillProperties(DiagnosticPropertiesBuilder description) { super.debugFillProperties(description); - description.add(new DiagnosticsProperty('current', _current, + description.add(DiagnosticsProperty('current', _current, ifNull: 'unresolved', showName: false)); - description.add(new ObjectFlagProperty>( + description.add(ObjectFlagProperty>( 'listeners', _listeners, ifPresent: @@ -260,7 +263,7 @@ class OneFramePictureStreamCompleter extends PictureStreamCompleter { {InformationCollector informationCollector}) : assert(picture != null) { picture.then(setImage, onError: (dynamic error, StackTrace stack) { - FlutterError.reportError(new FlutterErrorDetails( + FlutterError.reportError(FlutterErrorDetails( exception: error, stack: stack, library: 'SVG', diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index 8e18ea757b7f..6936af1f5685 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -1,4 +1,5 @@ import 'dart:math' as math; +import 'dart:ui' show window; import 'package:flutter/widgets.dart'; import 'package:meta/meta.dart'; @@ -21,7 +22,7 @@ class RawPicture extends LeafRenderObjectWidget { @override RenderPicture createRenderObject(BuildContext context) { - return new RenderPicture( + return RenderPicture( picture: picture, matchTextDirection: matchTextDirection, textDirection: matchTextDirection ? Directionality.of(context) : null, @@ -51,7 +52,7 @@ class RawPicture extends LeafRenderObjectWidget { class RenderPicture extends RenderBox { RenderPicture({ PictureInfo picture, - bool matchTextDirection: false, + bool matchTextDirection = false, TextDirection textDirection, bool allowDrawingOutsideViewBox, }) : _picture = picture, @@ -150,13 +151,13 @@ class RenderPicture extends RenderBox { // creates a red border around the drawing // context.canvas.drawRect( // Offset.zero & size, - // new Paint() + // Paint() // ..color = const Color(0xFFFA0000) // ..style = PaintingStyle.stroke); - scaleCanvasToViewBox(context.canvas, size, picture.viewBox); + scaleCanvasToViewBox(context.canvas, size, picture.viewport); if (allowDrawingOutsideViewBox != true) { - context.canvas.clipRect(picture.viewBox); + context.canvas.clipRect(picture.viewport); } context.canvas.drawPicture(picture.picture); context.canvas.restore(); @@ -164,6 +165,9 @@ class RenderPicture extends RenderBox { } void scaleCanvasToViewBox(Canvas canvas, Size desiredSize, Rect viewBox) { + // if (desiredSize == viewBox.size) { + // return; + // } final double scale = math.min( desiredSize.width / viewBox.width, desiredSize.height / viewBox.height); final Offset shift = desiredSize / 2.0 - viewBox.size * scale / 2.0; diff --git a/third_party/lib/src/svg/colors.dart b/third_party/lib/src/svg/colors.dart index 08f77957da01..c2551dfeeefb 100644 --- a/third_party/lib/src/svg/colors.dart +++ b/third_party/lib/src/svg/colors.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -const Color colorBlack = const Color(0xFF000000); +const Color colorBlack = Color(0xFF000000); /// Converts a SVG Color String (either a # prefixed color string or a named color) to a [Color]. Color parseColor(String colorString) { @@ -23,11 +23,11 @@ Color parseColor(String colorString) { int color = int.parse(colorString.substring(1), radix: 16); if (colorString.length == 7) { - return new Color(color |= 0xFF000000); + return Color(color |= 0xFF000000); } if (colorString.length == 9) { - return new Color(color); + return Color(color); } } @@ -47,7 +47,7 @@ Color parseColor(String colorString) { // rgba() isn't really in the spec, but Firefox supported it at one point so why not. final int a = rgb.length > 3 ? rgb[3] : 255; - return new Color.fromARGB(a, rgb[0], rgb[1], rgb[2]); + return Color.fromARGB(a, rgb[0], rgb[1], rgb[2]); } // handle named colors ('red', 'green', etc.). @@ -56,156 +56,156 @@ Color parseColor(String colorString) { return namedColor; } - throw new StateError('Could not parse "$colorString" as a color.'); + throw StateError('Could not parse "$colorString" as a color.'); } // https://www.w3.org/TR/SVG11/types.html#ColorKeywords -const Map _namedColors = const { - 'aliceblue': const Color.fromARGB(255, 240, 248, 255), - 'antiquewhite': const Color.fromARGB(255, 250, 235, 215), - 'aqua': const Color.fromARGB(255, 0, 255, 255), - 'aquamarine': const Color.fromARGB(255, 127, 255, 212), - 'azure': const Color.fromARGB(255, 240, 255, 255), - 'beige': const Color.fromARGB(255, 245, 245, 220), - 'bisque': const Color.fromARGB(255, 255, 228, 196), - 'black': const Color.fromARGB(255, 0, 0, 0), - 'blanchedalmond': const Color.fromARGB(255, 255, 235, 205), - 'blue': const Color.fromARGB(255, 0, 0, 255), - 'blueviolet': const Color.fromARGB(255, 138, 43, 226), - 'brown': const Color.fromARGB(255, 165, 42, 42), - 'burlywood': const Color.fromARGB(255, 222, 184, 135), - 'cadetblue': const Color.fromARGB(255, 95, 158, 160), - 'chartreuse': const Color.fromARGB(255, 127, 255, 0), - 'chocolate': const Color.fromARGB(255, 210, 105, 30), - 'coral': const Color.fromARGB(255, 255, 127, 80), - 'cornflowerblue': const Color.fromARGB(255, 100, 149, 237), - 'cornsilk': const Color.fromARGB(255, 255, 248, 220), - 'crimson': const Color.fromARGB(255, 220, 20, 60), - 'cyan': const Color.fromARGB(255, 0, 255, 255), - 'darkblue': const Color.fromARGB(255, 0, 0, 139), - 'darkcyan': const Color.fromARGB(255, 0, 139, 139), - 'darkgoldenrod': const Color.fromARGB(255, 184, 134, 11), - 'darkgray': const Color.fromARGB(255, 169, 169, 169), - 'darkgreen': const Color.fromARGB(255, 0, 100, 0), - 'darkgrey': const Color.fromARGB(255, 169, 169, 169), - 'darkkhaki': const Color.fromARGB(255, 189, 183, 107), - 'darkmagenta': const Color.fromARGB(255, 139, 0, 139), - 'darkolivegreen': const Color.fromARGB(255, 85, 107, 47), - 'darkorange': const Color.fromARGB(255, 255, 140, 0), - 'darkorchid': const Color.fromARGB(255, 153, 50, 204), - 'darkred': const Color.fromARGB(255, 139, 0, 0), - 'darksalmon': const Color.fromARGB(255, 233, 150, 122), - 'darkseagreen': const Color.fromARGB(255, 143, 188, 143), - 'darkslateblue': const Color.fromARGB(255, 72, 61, 139), - 'darkslategray': const Color.fromARGB(255, 47, 79, 79), - 'darkslategrey': const Color.fromARGB(255, 47, 79, 79), - 'darkturquoise': const Color.fromARGB(255, 0, 206, 209), - 'darkviolet': const Color.fromARGB(255, 148, 0, 211), - 'deeppink': const Color.fromARGB(255, 255, 20, 147), - 'deepskyblue': const Color.fromARGB(255, 0, 191, 255), - 'dimgray': const Color.fromARGB(255, 105, 105, 105), - 'dimgrey': const Color.fromARGB(255, 105, 105, 105), - 'dodgerblue': const Color.fromARGB(255, 30, 144, 255), - 'firebrick': const Color.fromARGB(255, 178, 34, 34), - 'floralwhite': const Color.fromARGB(255, 255, 250, 240), - 'forestgreen': const Color.fromARGB(255, 34, 139, 34), - 'fuchsia': const Color.fromARGB(255, 255, 0, 255), - 'gainsboro': const Color.fromARGB(255, 220, 220, 220), - 'ghostwhite': const Color.fromARGB(255, 248, 248, 255), - 'gold': const Color.fromARGB(255, 255, 215, 0), - 'goldenrod': const Color.fromARGB(255, 218, 165, 32), - 'gray': const Color.fromARGB(255, 128, 128, 128), - 'grey': const Color.fromARGB(255, 128, 128, 128), - 'green': const Color.fromARGB(255, 0, 128, 0), - 'greenyellow': const Color.fromARGB(255, 173, 255, 47), - 'honeydew': const Color.fromARGB(255, 240, 255, 240), - 'hotpink': const Color.fromARGB(255, 255, 105, 180), - 'indianred': const Color.fromARGB(255, 205, 92, 92), - 'indigo': const Color.fromARGB(255, 75, 0, 130), - 'ivory': const Color.fromARGB(255, 255, 255, 240), - 'khaki': const Color.fromARGB(255, 240, 230, 140), - 'lavender': const Color.fromARGB(255, 230, 230, 250), - 'lavenderblush': const Color.fromARGB(255, 255, 240, 245), - 'lawngreen': const Color.fromARGB(255, 124, 252, 0), - 'lemonchiffon': const Color.fromARGB(255, 255, 250, 205), - 'lightblue': const Color.fromARGB(255, 173, 216, 230), - 'lightcoral': const Color.fromARGB(255, 240, 128, 128), - 'lightcyan': const Color.fromARGB(255, 224, 255, 255), - 'lightgoldenrodyellow': const Color.fromARGB(255, 250, 250, 210), - 'lightgray': const Color.fromARGB(255, 211, 211, 211), - 'lightgreen': const Color.fromARGB(255, 144, 238, 144), - 'lightgrey': const Color.fromARGB(255, 211, 211, 211), - 'lightpink': const Color.fromARGB(255, 255, 182, 193), - 'lightsalmon': const Color.fromARGB(255, 255, 160, 122), - 'lightseagreen': const Color.fromARGB(255, 32, 178, 170), - 'lightskyblue': const Color.fromARGB(255, 135, 206, 250), - 'lightslategray': const Color.fromARGB(255, 119, 136, 153), - 'lightslategrey': const Color.fromARGB(255, 119, 136, 153), - 'lightsteelblue': const Color.fromARGB(255, 176, 196, 222), - 'lightyellow': const Color.fromARGB(255, 255, 255, 224), - 'lime': const Color.fromARGB(255, 0, 255, 0), - 'limegreen': const Color.fromARGB(255, 50, 205, 50), - 'linen': const Color.fromARGB(255, 250, 240, 230), - 'magenta': const Color.fromARGB(255, 255, 0, 255), - 'maroon': const Color.fromARGB(255, 128, 0, 0), - 'mediumaquamarine': const Color.fromARGB(255, 102, 205, 170), - 'mediumblue': const Color.fromARGB(255, 0, 0, 205), - 'mediumorchid': const Color.fromARGB(255, 186, 85, 211), - 'mediumpurple': const Color.fromARGB(255, 147, 112, 219), - 'mediumseagreen': const Color.fromARGB(255, 60, 179, 113), - 'mediumslateblue': const Color.fromARGB(255, 123, 104, 238), - 'mediumspringgreen': const Color.fromARGB(255, 0, 250, 154), - 'mediumturquoise': const Color.fromARGB(255, 72, 209, 204), - 'mediumvioletred': const Color.fromARGB(255, 199, 21, 133), - 'midnightblue': const Color.fromARGB(255, 25, 25, 112), - 'mintcream': const Color.fromARGB(255, 245, 255, 250), - 'mistyrose': const Color.fromARGB(255, 255, 228, 225), - 'moccasin': const Color.fromARGB(255, 255, 228, 181), - 'navajowhite': const Color.fromARGB(255, 255, 222, 173), - 'navy': const Color.fromARGB(255, 0, 0, 128), - 'oldlace': const Color.fromARGB(255, 253, 245, 230), - 'olive': const Color.fromARGB(255, 128, 128, 0), - 'olivedrab': const Color.fromARGB(255, 107, 142, 35), - 'orange': const Color.fromARGB(255, 255, 165, 0), - 'orangered': const Color.fromARGB(255, 255, 69, 0), - 'orchid': const Color.fromARGB(255, 218, 112, 214), - 'palegoldenrod': const Color.fromARGB(255, 238, 232, 170), - 'palegreen': const Color.fromARGB(255, 152, 251, 152), - 'paleturquoise': const Color.fromARGB(255, 175, 238, 238), - 'palevioletred': const Color.fromARGB(255, 219, 112, 147), - 'papayawhip': const Color.fromARGB(255, 255, 239, 213), - 'peachpuff': const Color.fromARGB(255, 255, 218, 185), - 'peru': const Color.fromARGB(255, 205, 133, 63), - 'pink': const Color.fromARGB(255, 255, 192, 203), - 'plum': const Color.fromARGB(255, 221, 160, 221), - 'powderblue': const Color.fromARGB(255, 176, 224, 230), - 'purple': const Color.fromARGB(255, 128, 0, 128), - 'red': const Color.fromARGB(255, 255, 0, 0), - 'rosybrown': const Color.fromARGB(255, 188, 143, 143), - 'royalblue': const Color.fromARGB(255, 65, 105, 225), - 'saddlebrown': const Color.fromARGB(255, 139, 69, 19), - 'salmon': const Color.fromARGB(255, 250, 128, 114), - 'sandybrown': const Color.fromARGB(255, 244, 164, 96), - 'seagreen': const Color.fromARGB(255, 46, 139, 87), - 'seashell': const Color.fromARGB(255, 255, 245, 238), - 'sienna': const Color.fromARGB(255, 160, 82, 45), - 'silver': const Color.fromARGB(255, 192, 192, 192), - 'skyblue': const Color.fromARGB(255, 135, 206, 235), - 'slateblue': const Color.fromARGB(255, 106, 90, 205), - 'slategray': const Color.fromARGB(255, 112, 128, 144), - 'slategrey': const Color.fromARGB(255, 112, 128, 144), - 'snow': const Color.fromARGB(255, 255, 250, 250), - 'springgreen': const Color.fromARGB(255, 0, 255, 127), - 'steelblue': const Color.fromARGB(255, 70, 130, 180), - 'tan': const Color.fromARGB(255, 210, 180, 140), - 'teal': const Color.fromARGB(255, 0, 128, 128), - 'thistle': const Color.fromARGB(255, 216, 191, 216), - 'tomato': const Color.fromARGB(255, 255, 99, 71), - 'turquoise': const Color.fromARGB(255, 64, 224, 208), - 'violet': const Color.fromARGB(255, 238, 130, 238), - 'wheat': const Color.fromARGB(255, 245, 222, 179), - 'white': const Color.fromARGB(255, 255, 255, 255), - 'whitesmoke': const Color.fromARGB(255, 245, 245, 245), - 'yellow': const Color.fromARGB(255, 255, 255, 0), - 'yellowgreen': const Color.fromARGB(255, 154, 205, 50), +const Map _namedColors = { + 'aliceblue': Color.fromARGB(255, 240, 248, 255), + 'antiquewhite': Color.fromARGB(255, 250, 235, 215), + 'aqua': Color.fromARGB(255, 0, 255, 255), + 'aquamarine': Color.fromARGB(255, 127, 255, 212), + 'azure': Color.fromARGB(255, 240, 255, 255), + 'beige': Color.fromARGB(255, 245, 245, 220), + 'bisque': Color.fromARGB(255, 255, 228, 196), + 'black': Color.fromARGB(255, 0, 0, 0), + 'blanchedalmond': Color.fromARGB(255, 255, 235, 205), + 'blue': Color.fromARGB(255, 0, 0, 255), + 'blueviolet': Color.fromARGB(255, 138, 43, 226), + 'brown': Color.fromARGB(255, 165, 42, 42), + 'burlywood': Color.fromARGB(255, 222, 184, 135), + 'cadetblue': Color.fromARGB(255, 95, 158, 160), + 'chartreuse': Color.fromARGB(255, 127, 255, 0), + 'chocolate': Color.fromARGB(255, 210, 105, 30), + 'coral': Color.fromARGB(255, 255, 127, 80), + 'cornflowerblue': Color.fromARGB(255, 100, 149, 237), + 'cornsilk': Color.fromARGB(255, 255, 248, 220), + 'crimson': Color.fromARGB(255, 220, 20, 60), + 'cyan': Color.fromARGB(255, 0, 255, 255), + 'darkblue': Color.fromARGB(255, 0, 0, 139), + 'darkcyan': Color.fromARGB(255, 0, 139, 139), + 'darkgoldenrod': Color.fromARGB(255, 184, 134, 11), + 'darkgray': Color.fromARGB(255, 169, 169, 169), + 'darkgreen': Color.fromARGB(255, 0, 100, 0), + 'darkgrey': Color.fromARGB(255, 169, 169, 169), + 'darkkhaki': Color.fromARGB(255, 189, 183, 107), + 'darkmagenta': Color.fromARGB(255, 139, 0, 139), + 'darkolivegreen': Color.fromARGB(255, 85, 107, 47), + 'darkorange': Color.fromARGB(255, 255, 140, 0), + 'darkorchid': Color.fromARGB(255, 153, 50, 204), + 'darkred': Color.fromARGB(255, 139, 0, 0), + 'darksalmon': Color.fromARGB(255, 233, 150, 122), + 'darkseagreen': Color.fromARGB(255, 143, 188, 143), + 'darkslateblue': Color.fromARGB(255, 72, 61, 139), + 'darkslategray': Color.fromARGB(255, 47, 79, 79), + 'darkslategrey': Color.fromARGB(255, 47, 79, 79), + 'darkturquoise': Color.fromARGB(255, 0, 206, 209), + 'darkviolet': Color.fromARGB(255, 148, 0, 211), + 'deeppink': Color.fromARGB(255, 255, 20, 147), + 'deepskyblue': Color.fromARGB(255, 0, 191, 255), + 'dimgray': Color.fromARGB(255, 105, 105, 105), + 'dimgrey': Color.fromARGB(255, 105, 105, 105), + 'dodgerblue': Color.fromARGB(255, 30, 144, 255), + 'firebrick': Color.fromARGB(255, 178, 34, 34), + 'floralwhite': Color.fromARGB(255, 255, 250, 240), + 'forestgreen': Color.fromARGB(255, 34, 139, 34), + 'fuchsia': Color.fromARGB(255, 255, 0, 255), + 'gainsboro': Color.fromARGB(255, 220, 220, 220), + 'ghostwhite': Color.fromARGB(255, 248, 248, 255), + 'gold': Color.fromARGB(255, 255, 215, 0), + 'goldenrod': Color.fromARGB(255, 218, 165, 32), + 'gray': Color.fromARGB(255, 128, 128, 128), + 'grey': Color.fromARGB(255, 128, 128, 128), + 'green': Color.fromARGB(255, 0, 128, 0), + 'greenyellow': Color.fromARGB(255, 173, 255, 47), + 'honeydew': Color.fromARGB(255, 240, 255, 240), + 'hotpink': Color.fromARGB(255, 255, 105, 180), + 'indianred': Color.fromARGB(255, 205, 92, 92), + 'indigo': Color.fromARGB(255, 75, 0, 130), + 'ivory': Color.fromARGB(255, 255, 255, 240), + 'khaki': Color.fromARGB(255, 240, 230, 140), + 'lavender': Color.fromARGB(255, 230, 230, 250), + 'lavenderblush': Color.fromARGB(255, 255, 240, 245), + 'lawngreen': Color.fromARGB(255, 124, 252, 0), + 'lemonchiffon': Color.fromARGB(255, 255, 250, 205), + 'lightblue': Color.fromARGB(255, 173, 216, 230), + 'lightcoral': Color.fromARGB(255, 240, 128, 128), + 'lightcyan': Color.fromARGB(255, 224, 255, 255), + 'lightgoldenrodyellow': Color.fromARGB(255, 250, 250, 210), + 'lightgray': Color.fromARGB(255, 211, 211, 211), + 'lightgreen': Color.fromARGB(255, 144, 238, 144), + 'lightgrey': Color.fromARGB(255, 211, 211, 211), + 'lightpink': Color.fromARGB(255, 255, 182, 193), + 'lightsalmon': Color.fromARGB(255, 255, 160, 122), + 'lightseagreen': Color.fromARGB(255, 32, 178, 170), + 'lightskyblue': Color.fromARGB(255, 135, 206, 250), + 'lightslategray': Color.fromARGB(255, 119, 136, 153), + 'lightslategrey': Color.fromARGB(255, 119, 136, 153), + 'lightsteelblue': Color.fromARGB(255, 176, 196, 222), + 'lightyellow': Color.fromARGB(255, 255, 255, 224), + 'lime': Color.fromARGB(255, 0, 255, 0), + 'limegreen': Color.fromARGB(255, 50, 205, 50), + 'linen': Color.fromARGB(255, 250, 240, 230), + 'magenta': Color.fromARGB(255, 255, 0, 255), + 'maroon': Color.fromARGB(255, 128, 0, 0), + 'mediumaquamarine': Color.fromARGB(255, 102, 205, 170), + 'mediumblue': Color.fromARGB(255, 0, 0, 205), + 'mediumorchid': Color.fromARGB(255, 186, 85, 211), + 'mediumpurple': Color.fromARGB(255, 147, 112, 219), + 'mediumseagreen': Color.fromARGB(255, 60, 179, 113), + 'mediumslateblue': Color.fromARGB(255, 123, 104, 238), + 'mediumspringgreen': Color.fromARGB(255, 0, 250, 154), + 'mediumturquoise': Color.fromARGB(255, 72, 209, 204), + 'mediumvioletred': Color.fromARGB(255, 199, 21, 133), + 'midnightblue': Color.fromARGB(255, 25, 25, 112), + 'mintcream': Color.fromARGB(255, 245, 255, 250), + 'mistyrose': Color.fromARGB(255, 255, 228, 225), + 'moccasin': Color.fromARGB(255, 255, 228, 181), + 'navajowhite': Color.fromARGB(255, 255, 222, 173), + 'navy': Color.fromARGB(255, 0, 0, 128), + 'oldlace': Color.fromARGB(255, 253, 245, 230), + 'olive': Color.fromARGB(255, 128, 128, 0), + 'olivedrab': Color.fromARGB(255, 107, 142, 35), + 'orange': Color.fromARGB(255, 255, 165, 0), + 'orangered': Color.fromARGB(255, 255, 69, 0), + 'orchid': Color.fromARGB(255, 218, 112, 214), + 'palegoldenrod': Color.fromARGB(255, 238, 232, 170), + 'palegreen': Color.fromARGB(255, 152, 251, 152), + 'paleturquoise': Color.fromARGB(255, 175, 238, 238), + 'palevioletred': Color.fromARGB(255, 219, 112, 147), + 'papayawhip': Color.fromARGB(255, 255, 239, 213), + 'peachpuff': Color.fromARGB(255, 255, 218, 185), + 'peru': Color.fromARGB(255, 205, 133, 63), + 'pink': Color.fromARGB(255, 255, 192, 203), + 'plum': Color.fromARGB(255, 221, 160, 221), + 'powderblue': Color.fromARGB(255, 176, 224, 230), + 'purple': Color.fromARGB(255, 128, 0, 128), + 'red': Color.fromARGB(255, 255, 0, 0), + 'rosybrown': Color.fromARGB(255, 188, 143, 143), + 'royalblue': Color.fromARGB(255, 65, 105, 225), + 'saddlebrown': Color.fromARGB(255, 139, 69, 19), + 'salmon': Color.fromARGB(255, 250, 128, 114), + 'sandybrown': Color.fromARGB(255, 244, 164, 96), + 'seagreen': Color.fromARGB(255, 46, 139, 87), + 'seashell': Color.fromARGB(255, 255, 245, 238), + 'sienna': Color.fromARGB(255, 160, 82, 45), + 'silver': Color.fromARGB(255, 192, 192, 192), + 'skyblue': Color.fromARGB(255, 135, 206, 235), + 'slateblue': Color.fromARGB(255, 106, 90, 205), + 'slategray': Color.fromARGB(255, 112, 128, 144), + 'slategrey': Color.fromARGB(255, 112, 128, 144), + 'snow': Color.fromARGB(255, 255, 250, 250), + 'springgreen': Color.fromARGB(255, 0, 255, 127), + 'steelblue': Color.fromARGB(255, 70, 130, 180), + 'tan': Color.fromARGB(255, 210, 180, 140), + 'teal': Color.fromARGB(255, 0, 128, 128), + 'thistle': Color.fromARGB(255, 216, 191, 216), + 'tomato': Color.fromARGB(255, 255, 99, 71), + 'turquoise': Color.fromARGB(255, 64, 224, 208), + 'violet': Color.fromARGB(255, 238, 130, 238), + 'wheat': Color.fromARGB(255, 245, 222, 179), + 'white': Color.fromARGB(255, 255, 255, 255), + 'whitesmoke': Color.fromARGB(255, 245, 245, 245), + 'yellow': Color.fromARGB(255, 255, 255, 0), + 'yellowgreen': Color.fromARGB(255, 154, 205, 50), }; diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index 6483493a06c0..092c779ba087 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -44,7 +44,7 @@ double parseFontSize(String raw, {double parentValue}) { return parentValue / 1.2; } - throw new StateError('Could not parse font-size: $raw'); + throw StateError('Could not parse font-size: $raw'); } DrawableTextAnchorPosition parseTextAnchor(String raw) { @@ -61,12 +61,12 @@ DrawableTextAnchorPosition parseTextAnchor(String raw) { } const String _transformCommandAtom = ' *([^(]+)\\(([^)]*)\\)'; -final RegExp _transformValidator = new RegExp('^($_transformCommandAtom)*\$'); -final RegExp _transformCommand = new RegExp(_transformCommandAtom); +final RegExp _transformValidator = RegExp('^($_transformCommandAtom)*\$'); +final RegExp _transformCommand = RegExp(_transformCommandAtom); -typedef Matrix4 MatrixParser(String paramsStr, Matrix4 current); +typedef MatrixParser = Matrix4 Function(String paramsStr, Matrix4 current); -const Map _matrixParsers = const { +const Map _matrixParsers = { 'matrix': _parseSvgMatrix, 'translate': _parseSvgTranslate, 'scale': _parseSvgScale, @@ -85,17 +85,17 @@ Matrix4 parseTransform(String transform) { } if (!_transformValidator.hasMatch(transform)) - throw new StateError('illegal or unsupported transform: $transform'); + throw StateError('illegal or unsupported transform: $transform'); final Iterable matches = _transformCommand.allMatches(transform).toList().reversed; - Matrix4 result = new Matrix4.identity(); + Matrix4 result = Matrix4.identity(); for (Match m in matches) { final String command = m.group(1); final String params = m.group(2); final MatrixParser transformer = _matrixParsers[command]; if (transformer == null) { - throw new StateError('Unsupported transform: $command'); + throw StateError('Unsupported transform: $command'); } result = transformer(params, result); @@ -103,7 +103,7 @@ Matrix4 parseTransform(String transform) { return result; } -final RegExp _valueSeparator = new RegExp('( *, *| +)'); +final RegExp _valueSeparator = RegExp('( *, *| +)'); Matrix4 _parseSvgMatrix(String paramsStr, Matrix4 current) { final List params = paramsStr.split(_valueSeparator); @@ -169,7 +169,7 @@ Matrix4 _parseSvgRotate(String paramsStr, Matrix4 current) { Matrix4 affineMatrix( double a, double b, double c, double d, double e, double f) { - return new Matrix4( + return Matrix4( a, b, 0.0, 0.0, c, d, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, e, f, 0.0, 1.0); } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index af0037c6cd4a..7cd6bcde36da 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -10,10 +10,9 @@ import '../vector_drawable.dart'; import 'colors.dart'; import 'parsers.dart'; -typedef Path SvgPathFactory(XmlElement el); +typedef SvgPathFactory = Path Function(XmlElement el); -const Map svgPathParsers = - const { +const Map svgPathParsers = { 'circle': parsePathFromCircle, 'path': parsePathFromPath, 'rect': parsePathFromRect, @@ -23,44 +22,74 @@ const Map svgPathParsers = 'line': parsePathFromLine, }; +double _parseRawWidthHeight(String raw) { + if (raw == '100%' || raw == '') { + return double.infinity; + } + assert(() { + final RegExp notDigits = RegExp(r'[^\d\.]'); + if (!raw.endsWith('px') && raw.contains(notDigits)) { + print( + 'Warning: Flutter SVG only supports the following formats for `width` and `height` on the SVG root:\n' + ' width="100%"\n' + ' width="100px"\n' + ' width="100" (where the number will be treated as pixels).\n' + 'The supplied value ($raw) will be discarded and treated as if it had not been specified.'); + } + return true; + }()); + return double.tryParse(raw.replaceAll('px', '')) ?? double.infinity; +} + /// Parses an SVG @viewBox attribute (e.g. 0 0 100 100) to a [Rect]. -DrawableViewport parseViewBox(XmlElement svg, {bool nullOk = false}) { +/// +/// The [nullOk] parameter controls whether this function should throw if there is no +/// viewBox or width/height parameters. +/// +/// The [respectWidthHeight] parameter specifies whether `width` and `height` attributes +/// on the root SVG element should be treated in accordance with the specification. +DrawableViewport parseViewBox( + XmlElement svg, { + bool nullOk = false, +}) { final String viewBox = getAttribute(svg, 'viewBox'); + final String rawWidth = getAttribute(svg, 'width'); + final String rawHeight = getAttribute(svg, 'height'); - if (viewBox == '') { - final RegExp notDigits = new RegExp(r'[^\d\.]'); - final String rawWidth = - getAttribute(svg, 'width').replaceAll(notDigits, ''); - final String rawHeight = - getAttribute(svg, 'height').replaceAll(notDigits, ''); - if (rawWidth == '' || rawHeight == '') { - if (nullOk) { - return null; - } - throw new StateError('SVG did not specify dimensions\n\n' - 'The SVG library looks for a `viewBox` or `width` and `height` attribute ' - 'to determine the viewport boundary of the SVG. Note that these attributes, ' - 'as with all SVG attributes, are case sensitive.\n' - 'During processing, these attributes were found: ${svg.attributes}'); + if (viewBox == '' && rawWidth == '' && rawHeight == '') { + if (nullOk) { + return null; } - final double width = double.parse(rawWidth); - final double height = double.parse(rawHeight); - return new DrawableViewport(Rect.fromLTWH(0.0, 0.0, width, height)); + throw StateError('SVG did not specify dimensions\n\n' + 'The SVG library looks for a `viewBox` or `width` and `height` attribute ' + 'to determine the viewport boundary of the SVG. Note that these attributes, ' + 'as with all SVG attributes, are case sensitive.\n' + 'During processing, the following attributes were found:\n' + ' ${svg.attributes}'); } - final List parts = viewBox.split(new RegExp(r'[ ,]+')); + final double width = _parseRawWidthHeight(rawWidth); + final double height = double.tryParse(rawHeight) ?? double.infinity; + + if (viewBox == '') { + return DrawableViewport( + Size(width, height), + Size(width, height), + ); + } + + final List parts = viewBox.split(RegExp(r'[ ,]+')); if (parts.length < 4) { - throw new StateError('viewBox element must be 4 elements long'); + throw StateError('viewBox element must be 4 elements long'); } - return new DrawableViewport( - new Rect.fromLTWH( - 0.0, - 0.0, + return DrawableViewport( + Size(width, height), + Size( double.parse(parts[2]), double.parse(parts[3]), ), - offset: new Offset( + viewBoxOffset: Offset( -double.parse(parts[0]), -double.parse(parts[1]), ), @@ -141,8 +170,8 @@ PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { final TileMode spreadMethod = parseTileMode(el); final List stops = el.findElements('stop').toList(); - final List colors = new List(stops.length); - final List offsets = new List(stops.length); + final List colors = List(stops.length); + final List offsets = List(stops.length); parseStops(stops, colors, offsets); @@ -151,7 +180,7 @@ PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { return (Rect bounds) { Vector3 from, to; - Matrix4 transform = originalTransform?.clone() ?? new Matrix4.identity(); + Matrix4 transform = originalTransform?.clone() ?? Matrix4.identity(); if (isObjectBoundingBox) { final Matrix4 scale = @@ -160,27 +189,27 @@ PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); transform = translate.multiplied(scale)..multiply(transform); - final Offset fromOffset = new Offset( + final Offset fromOffset = Offset( _parseDecimalOrPercentage(x1), _parseDecimalOrPercentage(y1), ); - final Offset toOffset = new Offset( + final Offset toOffset = Offset( _parseDecimalOrPercentage(x2), _parseDecimalOrPercentage(y2), ); - from = new Vector3( + from = Vector3( fromOffset.dx, fromOffset.dy, 0.0, ); - to = new Vector3( + to = Vector3( toOffset.dx, toOffset.dy, 0.0, ); } else { - final Offset fromOffset = new Offset( + final Offset fromOffset = Offset( _isPercentage(x1) ? _parsePercentage(x1) * rootBounds.width + rootBounds.left : double.parse(x1), @@ -189,7 +218,7 @@ PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { : double.parse(y1), ); - final Offset toOffset = new Offset( + final Offset toOffset = Offset( _isPercentage(x2) ? _parsePercentage(x2) * rootBounds.width + rootBounds.left : double.parse(x2), @@ -198,8 +227,8 @@ PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { : double.parse(y2), ); - from = new Vector3(fromOffset.dx, fromOffset.dy, 0.0); - to = new Vector3(toOffset.dx, toOffset.dy, 0.0); + from = Vector3(fromOffset.dx, fromOffset.dy, 0.0); + to = Vector3(toOffset.dx, toOffset.dy, 0.0); } if (transform != null) { @@ -207,9 +236,9 @@ PaintServer parseLinearGradient(XmlElement el, Rect rootBounds) { to = transform.transform3(to); } - return new Gradient.linear( - new Offset(from.x, from.y), - new Offset(to.x, to.y), + return Gradient.linear( + Offset(from.x, from.y), + Offset(to.x, to.y), colors, offsets, spreadMethod, @@ -232,8 +261,8 @@ PaintServer parseRadialGradient(XmlElement el, Rect rootBounds) { final List stops = el.findElements('stop').toList(); - final List colors = new List(stops.length); - final List offsets = new List(stops.length); + final List colors = List(stops.length); + final List offsets = List(stops.length); parseStops(stops, colors, offsets); final Matrix4 originalTransform = @@ -241,7 +270,7 @@ PaintServer parseRadialGradient(XmlElement el, Rect rootBounds) { return (Rect bounds) { double cx, cy, r, fx, fy; - Matrix4 transform = originalTransform?.clone() ?? new Matrix4.identity(); + Matrix4 transform = originalTransform?.clone() ?? Matrix4.identity(); if (isObjectBoundingBox) { final Matrix4 scale = @@ -274,11 +303,11 @@ PaintServer parseRadialGradient(XmlElement el, Rect rootBounds) { : double.parse(rawFy); } - final Offset center = new Offset(cx, cy); + final Offset center = Offset(cx, cy); final Offset focal = - (fx != cx || fy != cy) ? new Offset(fx, fy) : new Offset(cx, cy); + (fx != cx || fy != cy) ? Offset(fx, fy) : Offset(cx, cy); - return new Gradient.radial( + return Gradient.radial( center, r, colors, @@ -334,7 +363,7 @@ PaintServer parseGradient(XmlElement el, Rect rootBounds) { } else if (el.name.local == 'radialGradient') { return parseRadialGradient(el, rootBounds); } - throw new StateError('Unknown gradient type ${el.name.local}'); + throw StateError('Unknown gradient type ${el.name.local}'); } /// Parses an @stroke-dasharray attribute into a [CircularIntervalList] @@ -348,8 +377,8 @@ CircularIntervalList parseDashArray(XmlElement el) { return DrawableStyle.emptyDashArray; } - final List parts = rawDashArray.split(new RegExp(r'[ ,]+')); - return new CircularIntervalList( + final List parts = rawDashArray.split(RegExp(r'[ ,]+')); + return CircularIntervalList( parts.map((String part) => double.parse(part)).toList()); } @@ -364,9 +393,9 @@ DashOffset parseDashOffset(XmlElement el) { final double percentage = double.parse(rawDashOffset.substring(0, rawDashOffset.length - 1)) / 100; - return new DashOffset.percentage(percentage); + return DashOffset.percentage(percentage); } else { - return new DashOffset.absolute(double.parse(rawDashOffset)); + return DashOffset.absolute(double.parse(rawDashOffset)); } } @@ -385,8 +414,8 @@ DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri, final Shader shader = definitions.getPaint(iri, bounds); if (shader == null) { FlutterError.onError( - new FlutterErrorDetails( - exception: new StateError('Failed to find definition for $iri'), + FlutterErrorDetails( + exception: StateError('Failed to find definition for $iri'), context: 'in _getDefinitionPaint', library: 'SVG', informationCollector: (StringBuffer buff) { @@ -401,10 +430,10 @@ DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri, ); } - return new DrawablePaint( + return DrawablePaint( paintingStyle, shader: shader, - color: opacity != null ? new Color.fromRGBO(255, 255, 255, opacity) : null, + color: opacity != null ? Color.fromRGBO(255, 255, 255, opacity) : null, ); } @@ -443,7 +472,7 @@ DrawablePaint parseStroke( final String rawMiterLimit = getAttribute(el, 'stroke-miterlimit'); final String rawStrokeWidth = getAttribute(el, 'stroke-width'); - final DrawablePaint paint = new DrawablePaint( + final DrawablePaint paint = DrawablePaint( PaintingStyle.stroke, color: rawStroke == '' ? (parentStroke?.color ?? colorBlack).withOpacity(opacity) @@ -499,7 +528,7 @@ DrawablePaint parseFill( return DrawablePaint.empty; } - return new DrawablePaint( + return DrawablePaint( PaintingStyle.fill, color: rawFill == '' ? (parentFill?.color ?? colorBlack).withOpacity(opacity) @@ -518,7 +547,7 @@ Path parsePathFromRect(XmlElement el) { final double y = double.parse(getAttribute(el, 'y', def: '0')); final double w = double.parse(getAttribute(el, 'width', def: '0')); final double h = double.parse(getAttribute(el, 'height', def: '0')); - final Rect rect = new Rect.fromLTWH(x, y, w, h); + final Rect rect = Rect.fromLTWH(x, y, w, h); String rxRaw = getAttribute(el, 'rx', def: null); String ryRaw = getAttribute(el, 'ry', def: null); rxRaw ??= ryRaw; @@ -528,10 +557,10 @@ Path parsePathFromRect(XmlElement el) { final double rx = double.parse(rxRaw); final double ry = double.parse(ryRaw); - return new Path()..addRRect(new RRect.fromRectXY(rect, rx, ry)); + return Path()..addRRect(RRect.fromRectXY(rect, rx, ry)); } - return new Path()..addRect(rect); + return Path()..addRect(rect); } Path parsePathFromLine(XmlElement el) { @@ -540,7 +569,7 @@ Path parsePathFromLine(XmlElement el) { final double y1 = double.parse(getAttribute(el, 'y1', def: '0')); final double y2 = double.parse(getAttribute(el, 'y2', def: '0')); - return new Path() + return Path() ..moveTo(x1, y1) ..lineTo(x2, y2); } @@ -572,8 +601,8 @@ Path parsePathFromCircle(XmlElement el) { final double cx = double.parse(getAttribute(el, 'cx', def: '0')); final double cy = double.parse(getAttribute(el, 'cy', def: '0')); final double r = double.parse(getAttribute(el, 'r', def: '0')); - final Rect oval = new Rect.fromCircle(center: new Offset(cx, cy), radius: r); - return new Path()..addOval(oval); + final Rect oval = Rect.fromCircle(center: Offset(cx, cy), radius: r); + return Path()..addOval(oval); } Path parsePathFromEllipse(XmlElement el) { @@ -582,8 +611,8 @@ Path parsePathFromEllipse(XmlElement el) { final double rx = double.parse(getAttribute(el, 'rx', def: '0')); final double ry = double.parse(getAttribute(el, 'ry', def: '0')); - final Rect r = new Rect.fromLTWH(cx - rx, cy - ry, rx * 2, ry * 2); - return new Path()..addOval(r); + final Rect r = Rect.fromLTWH(cx - rx, cy - ry, rx * 2, ry * 2); + return Path()..addOval(r); } Path applyTransformIfNeeded(Path path, XmlElement el) { diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index a67bc8ce76d8..1d432bd70470 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -23,7 +23,7 @@ class DrawableSvgShape extends DrawableShape { assert(pathFactory != null); final Path path = pathFactory(el); - return new DrawableSvgShape( + return DrawableSvgShape( path, parseStyle( el, @@ -61,33 +61,32 @@ Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, final SvgPathFactory shapeFn = svgPathParsers[el.name.local]; if (shapeFn != null) { - return new DrawableSvgShape.parse(shapeFn, definitions, el, parentStyle); + return DrawableSvgShape.parse(shapeFn, definitions, el, parentStyle); } else if (el.name.local == 'defs') { parseDefs(el, definitions, rootBounds).forEach(unhandled); - return new DrawableNoop(el.name.local); + return DrawableNoop(el.name.local); } else if (el.name.local.endsWith('Gradient')) { definitions.addPaintServer( 'url(#${getAttribute(el, 'id')})', parseGradient(el, rootBounds)); - return new DrawableNoop(el.name.local); + return DrawableNoop(el.name.local); } else if (el.name.local == 'g' || el.name.local == 'a') { return parseSvgGroup(el, definitions, rootBounds, parentStyle, key); } else if (el.name.local == 'text') { return parseSvgText(el, definitions, rootBounds, parentStyle); } else if (el.name.local == 'svg') { - throw new UnsupportedError( - 'Nested SVGs not supported in this implementation.'); + throw UnsupportedError('Nested SVGs not supported in this implementation.'); } unhandled(el); - return new DrawableNoop(el.name.local); + return DrawableNoop(el.name.local); } -Set _unhandledElements = new Set(); +Set _unhandledElements = Set(); void _unhandledElement(XmlElement el, String key) { if (el.name.local == 'style') { - FlutterError.reportError(new FlutterErrorDetails( - exception: new UnimplementedError( + FlutterError.reportError(FlutterErrorDetails( + exception: UnimplementedError( 'The -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 From de86cb49d98f38122274b9c04eb15353fae4e98e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 23 Nov 2018 22:41:53 -0800 Subject: [PATCH 169/512] fix width/height bugs --- third_party/example/lib/main.dart | 46 ++++++++++--- .../golden/simple/width_height_viewbox.png | Bin 1063 -> 540 bytes third_party/lib/avd.dart | 15 ++-- third_party/lib/src/picture_stream.dart | 12 +++- third_party/lib/src/render_picture.dart | 57 +++++++++++----- third_party/lib/src/svg/xml_parsers.dart | 2 +- third_party/lib/src/vector_drawable.dart | 64 ++++++++---------- third_party/lib/svg.dart | 47 ++++++++----- third_party/test/xml_svg_test.dart | 3 +- third_party/tool/gen_golden.dart | 2 +- 10 files changed, 155 insertions(+), 93 deletions(-) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index 46694e5c7405..05829c0bd275 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -6,7 +6,7 @@ import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; const List assetNames = [ - // // 'assets/notfound.svg', + // 'assets/notfound.svg', 'assets/flutter_logo.svg', 'assets/dart.svg', 'assets/simple/clip_path_3.svg', @@ -88,6 +88,42 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; + _painters.add( + SvgPicture.string( + ''' + + + Fill 1 + Created with Sketch. + + + + + + + + +''', + color: Colors.black, + ), + ); + + _painters.add(SvgPicture.string(''' + + + Close + Created with Sketch. + + + + + + + + + + +''')); for (String assetName in assetNames) { _painters.add( SvgPicture.asset(assetName), @@ -107,8 +143,6 @@ class _MyHomePageState extends State { ); } - // _painters.add(new SvgPicture.asset(iconNames[0], color: Colors.red)); - for (String uriName in uriNames) { _painters.add( SvgPicture.network( @@ -139,12 +173,6 @@ class _MyHomePageState extends State { onChanged: (double val) { setState(() => _dimension = val); }), - // FlutterLogo(size: _dimension), - // Container( - // padding: const EdgeInsets.all(12.0), - // child: - - // ) Expanded( child: GridView.extent( shrinkWrap: true, diff --git a/third_party/golden/simple/width_height_viewbox.png b/third_party/golden/simple/width_height_viewbox.png index d82895c0d2283d746e3613568f6aed2436d5181c..a5227551975c5b74545e9f6cefb6535767fc90cf 100644 GIT binary patch delta 361 zcmV-v0ha!!2%H3vKsW)$NkllDlr7{Lj2048ycWV^6H`loo* zqV{?UmOjrNKOmkLj_)-lAq11*122)F7k_vOyR|#;pVV6GBfe+1+j(vad0V>!@X7>a zCBra;uIob1`RZqK&Y|nNFbuirZ!DeQ%dzxO6lC*wrwq?oZHsE z4|s~Pz+;T(;-3r2G#t~A2*~o@*Y3c7bUYqI-}hgxP0ugeLI~k-I6S>yd}lReL4VU< z|D5w|5aygtr?B7e&*xUL*rZ$YjBCf-{ABI>fT#FY>32dh7Y+egmStYxHTaA5_ZUG| z^3zFr-}g5+6Jay%jT|YZn{7rAHf=2M-)t1d7zKoF8w7{Kw#YOl};XF!}*TLUz^!ZwK zU3(=V+@L^z{uIZ-6p{Sx8X_TD??Bq(ILH~vv9(1)q+Wq^iQ^zgBwg1O2~j!+(kG6C z$VmFGB@!ZZ3S>we2N97BT|*>{bu^GMaU6_^WNcs}VT{&5BH}n0a?qpRqKSl|S_7%; zI`lS@J_kPfLw;S?>HYmZY(2h))<7N}9#U0Rp%?6ba`1C}1Gd?0(#_3H=$f3qqn|;x z+wG*0rfl&JSqlhtaKo}ZsXH*s}!l|DW`Le~@r z5eAL@$q`8;aS&zD-Ml&8ZbcCXkp@2xQeq_HAlj%$ZcB@)4yKZ2^k~jV#KDxZ&E{P!7P*#&$z%y+ z&apobDLjxl2ggCQ&_L!KJqkI51v1Bh6$!b81TyDA6$v?w4y1$wTEZSUO``%S>0p+$ z7f#3EKuSE2CGLrT+n_*7K8Pjnjek$?Kyn;^z{|_a(Dg(@lwN`48qM?e_BP7|M>wW) zAi3vOO+CR8y66!EyKZ_vz{BDfEI}pXbOiobKi2#e{cy zX?+D*E|=-->@4hJeI9m-ekG}@N*wgo8py@PMS6XG4T)sPlYmi?R8^I>+wJIe_!FO`FD^Zkwgwy=o^VRh|ueo^gfZ~m_E`q z5^)fv_q|wMBFQh?Jjagf8Hf5G;v z-ENm|Z*SA%qB^N9UGQ9=TNQ avdPictureStringDecoder(String raw, bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter, String key) { - final DrawableRoot svg = fromAvdString(raw, key); + final DrawableRoot avd = fromAvdString(raw, key); return PictureInfo( - picture: svg.toPicture( - clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, - colorFilter: colorFilter), - viewport: svg.viewport.calculateViewportRect); + picture: avd.toPicture( + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, + colorFilter: colorFilter), + viewport: avd.viewport.viewBoxRect, + size: avd.viewport.size, + ); } FutureOr fromAvdBytes(Uint8List raw, String key) async { diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart index b89a85bc314f..687db8d2ba33 100644 --- a/third_party/lib/src/picture_stream.dart +++ b/third_party/lib/src/picture_stream.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:ui' show Picture, Rect, hashValues; +import 'dart:ui' show Picture, Rect, hashValues, Size; import 'package:flutter/foundation.dart'; @@ -17,8 +17,10 @@ class PictureInfo { const PictureInfo({ @required this.picture, @required this.viewport, + this.size = Size.infinite, }) : assert(picture != null), - assert(viewport != null); + assert(viewport != null), + assert(size != null); /// The raw picture. /// @@ -26,7 +28,11 @@ class PictureInfo { final Picture picture; /// The viewport enclosing the coordinates used in the picture. - final ViewportCalculator viewport; + final Rect viewport; + + /// The requested size for this picture, which may be different than the + /// [viewport.size]. + final Size size; @override String toString() => '$picture'; diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index 01d66c475470..8beb94d52378 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -69,6 +69,11 @@ class RenderPicture extends RenderBox { _allowDrawingOutsideViewBox = allowDrawingOutsideViewBox, _devicePixelRatio = devicePixelRatio; + /// Optional color to use to draw a thin rectangle around the canvas. + /// + /// Only applied if asserts are enabled (e.g. debug mode). + static Color debugRectColor; + /// The ratio of device pixels to logical pixels. /// /// This value will be used to appropriately scale the picture, if necessary. @@ -170,34 +175,50 @@ class RenderPicture extends RenderBox { context.canvas.scale(-1.0, 1.0); } - // this is sometimes useful for debugging, will remove - // creates a red border around the drawing - // context.canvas.drawRect( - // Offset.zero & size, - // Paint() - // ..color = const Color(0xFFFA0000) - // ..style = PaintingStyle.stroke); - + // this is sometimes useful for debugging, e.g. to draw + // a thin red border around the drawing. + assert(() { + if (RenderPicture.debugRectColor != null && + RenderPicture.debugRectColor.alpha > 0) { + context.canvas.drawRect( + Offset.zero & size, + Paint() + ..color = debugRectColor + ..style = PaintingStyle.stroke); + } + return true; + }()); + final Rect viewportRect = + Offset.zero & (_picture.viewport.size * _devicePixelRatio); scaleCanvasToViewBox( context.canvas, size, - picture.viewport(_devicePixelRatio), + _picture.viewport, + // _picture.size * devicePixelRatio, + _picture.size, ); if (allowDrawingOutsideViewBox != true) { - context.canvas.clipRect(picture.viewport(_devicePixelRatio)); + context.canvas.clipRect(viewportRect); } context.canvas.drawPicture(picture.picture); context.canvas.restore(); } } -void scaleCanvasToViewBox(Canvas canvas, Size desiredSize, Rect viewBox) { - if (desiredSize == viewBox.size) { - return; +void scaleCanvasToViewBox( + Canvas canvas, + Size desiredSize, + Rect viewBox, + Size pictureSize, +) { + if (pictureSize.isFinite) { + final Offset shift = desiredSize / 2.0 - pictureSize / 2.0; + canvas.translate(shift.dx, shift.dy); + } else if (desiredSize != viewBox.size) { + final double scale = math.min( + desiredSize.width / viewBox.width, desiredSize.height / viewBox.height); + final Offset shift = desiredSize / 2.0 - viewBox.size * scale / 2.0; + canvas.translate(shift.dx, shift.dy); + canvas.scale(scale, scale); } - final double scale = math.min( - desiredSize.width / viewBox.width, desiredSize.height / viewBox.height); - final Offset shift = desiredSize / 2.0 - viewBox.size * scale / 2.0; - canvas.translate(shift.dx, shift.dy); - canvas.scale(scale, scale); } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 7cd6bcde36da..edc5cbf0a6ba 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -69,7 +69,7 @@ DrawableViewport parseViewBox( } final double width = _parseRawWidthHeight(rawWidth); - final double height = double.tryParse(rawHeight) ?? double.infinity; + final double height = _parseRawWidthHeight(rawHeight); if (viewBox == '') { return DrawableViewport( diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 45d746d473dd..433976293ad8 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -470,20 +470,20 @@ class DrawableViewport { /// /// This [Rect] gets scaled by [devicePixelRatio] on non-infinite /// dimensions of [Size] (infinite dimensions of size are treated as "100%"). - Rect calculateViewportRect(double devicePixelRatio) { - if (size == Size.infinite) { - return viewBoxRect; - } - final Size viewportSize = Size( - size.width == double.infinity - ? viewBox.width - : size.width * devicePixelRatio, - size.height == double.infinity - ? viewBox.height - : size.height * devicePixelRatio, - ); - return Offset.zero & viewportSize; - } + // Rect calculateViewportRect(double devicePixelRatio) { + // if (size == Size.infinite) { + // return viewBoxRect; + // } + // final Size viewportSize = Size( + // size.width == double.infinity + // ? viewBox.width + // : size.width * devicePixelRatio, + // size.height == double.infinity + // ? viewBox.height + // : size.height * devicePixelRatio, + // ); + // return Offset.zero & viewportSize; + // } /// The viewBox size for the drawable. final Size viewBox; @@ -507,7 +507,11 @@ class DrawableViewport { /// The root element of a drawable. class DrawableRoot implements Drawable { const DrawableRoot( - this.viewport, this.children, this.definitions, this.style); + this.viewport, + this.children, + this.definitions, + this.style, + ); /// The expected coordinates used by child paths for drawing. final DrawableViewport viewport; @@ -530,32 +534,18 @@ class DrawableRoot implements Drawable { /// If the `viewBox` dimensions are not 1:1 with `desiredSize`, will scale to /// the smaller dimension and translate to center the image along the larger /// dimension. - /// - /// The [devicePixelRatio] parameter will be defaulted to the current - /// value of [window.devicePixelRatio]; if calling this with a [MediaQuery] - /// available, it is preferable to use the [MediaQuery.of(context).devicePixelRatio]. - void scaleCanvasToViewBox( - Canvas canvas, - Size desiredSize, { - double devicePixelRatio, - }) { - devicePixelRatio ??= window.devicePixelRatio; + void scaleCanvasToViewBox(Canvas canvas, Size desiredSize) { render_picture.scaleCanvasToViewBox( - canvas, desiredSize, viewport.calculateViewportRect(devicePixelRatio)); + canvas, + desiredSize, + viewport.viewBoxRect, + viewport.size, + ); } /// Clips the canvas to a rect corresponding to the `viewBox`. - /// - /// The [devicePixelRatio] parameter will be defaulted to the current - /// value of [window.devicePixelRatio]; if calling this with a [MediaQuery] - /// available, it is preferable to use the [MediaQuery.of(context).devicePixelRatio]. - void clipCanvasToViewBox( - Canvas canvas, { - double devicePixelRatio, - }) { - devicePixelRatio ??= window.devicePixelRatio; - - canvas.clipRect(viewport.calculateViewportRect(devicePixelRatio)); + void clipCanvasToViewBox(Canvas canvas) { + canvas.clipRect(viewport.viewBoxRect); } @override diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 871a3882e0e6..4ce354e5be4b 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -49,7 +49,10 @@ class Svg { clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter); return PictureInfo( - picture: pic, viewport: svgRoot.viewport.calculateViewportRect); + picture: pic, + viewport: svgRoot.viewport.viewBoxRect, + size: svgRoot.viewport.size, + ); } /// Produces a [PictureInfo] from a [String] of SVG data. @@ -66,10 +69,13 @@ class Svg { bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter, String key) { final DrawableRoot svg = fromSvgString(raw, key); return PictureInfo( - picture: svg.toPicture( - clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, - colorFilter: colorFilter), - viewport: svg.viewport.calculateViewportRect); + picture: svg.toPicture( + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, + colorFilter: colorFilter, + ), + viewport: svg.viewport.viewBoxRect, + size: svg.viewport.size, + ); } /// Produces a [Drawableroot] from a [Uint8List] of SVG byte data (assumes UTF8 encoding). @@ -601,17 +607,11 @@ class _SvgPictureState extends State { @override Widget build(BuildContext context) { if (_picture != null) { - Widget picture = RawPicture( - _picture, - matchTextDirection: widget.matchTextDirection, - allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, - ); - final Rect viewport = _picture.viewport( + final double devicePixelRatio = MediaQuery.of(context, nullOk: true)?.devicePixelRatio ?? - window.devicePixelRatio); - picture = SizedBox.fromSize(size: viewport.size, child: picture); - picture = FittedBox( - fit: widget.fit, alignment: widget.alignment, child: picture); + window.devicePixelRatio; + final Rect viewport = + Offset.zero & (_picture.viewport.size * devicePixelRatio); double width = widget.width; double height = widget.height; @@ -624,7 +624,22 @@ class _SvgPictureState extends State { height = width / viewport.width * viewport.height; } - return SizedBox(width: width, height: height, child: picture); + return SizedBox( + width: width, + height: height, + child: FittedBox( + fit: widget.fit, + alignment: widget.alignment, + child: SizedBox.fromSize( + size: viewport.size, + child: RawPicture( + _picture, + matchTextDirection: widget.matchTextDirection, + allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, + ), + ), + ), + ); } return widget.placeholderBuilder == null diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index aea0f65f4a25..310dce8f1eab 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -44,7 +44,7 @@ void main() { final XmlElement svgWithViewBox = parse('').rootElement; final XmlElement svgWithViewBoxAndWidthHeight = - parse('') + parse('') .rootElement; final XmlElement svgWithWidthHeight = parse('').rootElement; @@ -52,6 +52,7 @@ void main() { parse('').rootElement; final XmlElement svgWithNoSizeInfo = parse('').rootElement; + expect(parseViewBox(svgWithViewBoxAndWidthHeight).size, const Size(50, 50)); expect(parseViewBox(svgWithViewBox).viewBoxRect, rect); expect(parseViewBox(svgWithViewBox).viewBoxOffset, Offset.zero); expect(parseViewBox(svgWithViewBoxAndWidthHeight).viewBoxRect, rect); diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index 4d6ae544d7aa..7b544ea8e7ca 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -68,7 +68,7 @@ Future main() async { goldenDir.createSync(recursive: true); } final File output = File(pathName); - +print(pathName); await output.writeAsBytes(await getSvgPngBytes(await fe.readAsString())); } } From 152f39de514a8daa825bd2d68b074a7d511e0eb3 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sat, 24 Nov 2018 15:32:15 -0800 Subject: [PATCH 170/512] refer to shapes --- third_party/example/lib/main.dart | 58 +++++++--- third_party/lib/avd.dart | 2 +- third_party/lib/src/avd_parser.dart | 2 +- third_party/lib/src/picture_cache.dart | 2 +- third_party/lib/src/picture_provider.dart | 2 +- third_party/lib/src/render_picture.dart | 5 +- third_party/lib/src/svg/parsers.dart | 9 +- third_party/lib/src/svg/xml_parsers.dart | 2 + third_party/lib/src/svg_parser.dart | 93 ++++++++++++++-- third_party/lib/src/vector_drawable.dart | 128 +++++++++++++++++----- third_party/lib/svg.dart | 4 +- third_party/test/xml_svg_test.dart | 2 +- 12 files changed, 248 insertions(+), 61 deletions(-) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index 05829c0bd275..f34ce2d2df05 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -6,7 +6,7 @@ import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; const List assetNames = [ - // 'assets/notfound.svg', + // 'assets/notfound.svg', // uncomment to test an asset that doesn't exist. 'assets/flutter_logo.svg', 'assets/dart.svg', 'assets/simple/clip_path_3.svg', @@ -58,7 +58,6 @@ void main() { } class MyApp extends StatelessWidget { - // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( @@ -88,21 +87,52 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; + _painters.add(SvgPicture.string( + ''' + + + +''')); _painters.add( SvgPicture.string( ''' - - - Fill 1 - Created with Sketch. - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ''', color: Colors.black, ), diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 830c298bc86a..dd6747d124fb 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -45,7 +45,7 @@ class Avd { } FutureOr fromAvdBytes(Uint8List raw, String key) async { - // TODO - do utf decoding in another thread? + // TODO(dnfield): do utf decoding in another thread? // Might just have to live with potentially slow(ish) decoding, this is causing errors. // See: https://github.com/dart-lang/sdk/issues/31954 // See: https://github.com/flutter/flutter/blob/bf3bd7667f07709d0b817ebfcb6972782cfef637/packages/flutter/lib/src/services/asset_bundle.dart#L66 diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index ba3d6ce29c36..6d5617888957 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -45,7 +45,7 @@ Drawable parseAvdElement(XmlElement el, Rect bounds) { } else if (el.name.local == 'group') { return parseAvdGroup(el, bounds); } - // TODO: clipPath + // TODO(dnfield): clipPath print('Unhandled element ${el.name.local}'); return DrawableNoop(el.name.local); } diff --git a/third_party/lib/src/picture_cache.dart b/third_party/lib/src/picture_cache.dart index 06e8e6c3ea42..de676d61818a 100644 --- a/third_party/lib/src/picture_cache.dart +++ b/third_party/lib/src/picture_cache.dart @@ -2,7 +2,7 @@ import 'picture_stream.dart'; const int _kDefaultSize = 1000; -// TODO: Implement memory based limiting, once `approximateByteCount` is exposed in engine +// TODO(dnfield): Implement memory based limiting, once `approximateByteCount` is exposed in engine class PictureCache { final Map _cache = {}; diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index f47f85a5fa79..382706e0d076 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -187,7 +187,7 @@ class PictureConfiguration { } } -// TODO: allow other people to implement this. +// TODO(dnfield): allow other people to implement this. PictureCache _cache = PictureCache(); /// Identifies a picture without committing to the precise final asset. This diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index 8beb94d52378..c9686e2a257d 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -194,7 +194,6 @@ class RenderPicture extends RenderBox { context.canvas, size, _picture.viewport, - // _picture.size * devicePixelRatio, _picture.size, ); if (allowDrawingOutsideViewBox != true) { @@ -216,7 +215,9 @@ void scaleCanvasToViewBox( canvas.translate(shift.dx, shift.dy); } else if (desiredSize != viewBox.size) { final double scale = math.min( - desiredSize.width / viewBox.width, desiredSize.height / viewBox.height); + desiredSize.width / viewBox.width, + desiredSize.height / viewBox.height, + ); final Offset shift = desiredSize / 2.0 - viewBox.size * scale / 2.0; canvas.translate(shift.dx, shift.dy); canvas.scale(scale, scale); diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index 092c779ba087..03f87296606e 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -79,7 +79,14 @@ const Map _matrixParsers = { /// /// Based on work in the "vi-tool" by @amirh, but extended to support additional /// transforms and use a Matrix4 rather than Matrix3 for the affine matrices. -Matrix4 parseTransform(String transform) { +/// +/// Also adds [x] and [y] to append as a final translation, e.g. for ``. +Matrix4 parseTransform(String transform, [String x, String y]) { + if (x != null || y != null) { + x ??= '0'; + y ??= '0'; + transform = '$transform translate($x $y)'; + } if (transform == null || transform == '') { return null; } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index edc5cbf0a6ba..5ce17b5311f2 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -98,6 +98,8 @@ DrawableViewport parseViewBox( String buildUrlIri(XmlElement def) => 'url(#${getAttribute(def, 'id')})'; +const String emptyUrlIri = 'url(#)'; + /// Parses a element, extracting and elements into the `paintServers` map. /// /// Returns any elements it was not able to process. diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 1d432bd70470..6e814ae1db41 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -58,23 +58,97 @@ class DrawableSvgShape extends DrawableShape { Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, Rect rootBounds, DrawableStyle parentStyle, String key) { final Function unhandled = (XmlElement e) => _unhandledElement(e, key); + final Function createDefinition = (String iri, XmlElement defEl) { + assert(iri != emptyUrlIri); + definitions.addDrawable( + iri, + parseSvgElement( + defEl, + definitions, + rootBounds, + parentStyle, + key, + ), + ); + }; final SvgPathFactory shapeFn = svgPathParsers[el.name.local]; if (shapeFn != null) { - return DrawableSvgShape.parse(shapeFn, definitions, el, parentStyle); + final DrawableShape shape = + DrawableSvgShape.parse(shapeFn, definitions, el, parentStyle); + final String iri = buildUrlIri(el); + if (iri != emptyUrlIri) { + definitions.addDrawable(iri, shape); + } + return shape; } else if (el.name.local == 'defs') { - parseDefs(el, definitions, rootBounds).forEach(unhandled); + final Iterable unhandledDefs = parseDefs( + el, + definitions, + rootBounds, + ); + for (XmlElement unhandledDef in unhandledDefs) { + String iri = buildUrlIri(unhandledDef); + if (iri == emptyUrlIri) { + for (XmlElement child + in unhandledDef.children.whereType()) { + iri = buildUrlIri(child); + if (iri != emptyUrlIri) { + createDefinition(iri, child); + } + } + } else { + createDefinition(iri, unhandledDef); + } + } return DrawableNoop(el.name.local); } else if (el.name.local.endsWith('Gradient')) { definitions.addPaintServer( - 'url(#${getAttribute(el, 'id')})', parseGradient(el, rootBounds)); + 'url(#${getAttribute(el, 'id')})', + parseGradient(el, rootBounds), + ); return DrawableNoop(el.name.local); - } else if (el.name.local == 'g' || el.name.local == 'a') { - return parseSvgGroup(el, definitions, rootBounds, parentStyle, key); + } else if (el.name.local == 'g' || + el.name.local == 'a' || + el.name.local == 'symbol') { + final DrawableGroup group = parseSvgGroup( + el, + definitions, + rootBounds, + parentStyle, + key, + ); + final String iri = buildUrlIri(el); + if (iri != emptyUrlIri) { + definitions.addDrawable(iri, group); + } + return group; } else if (el.name.local == 'text') { return parseSvgText(el, definitions, rootBounds, parentStyle); } else if (el.name.local == 'svg') { throw UnsupportedError('Nested SVGs not supported in this implementation.'); + } else if (el.name.local == 'use') { + final String xlinkHref = getAttribute( + el, + 'href', + namespace: 'http://www.w3.org/1999/xlink', + def: getAttribute(el, 'href'), + ); + print(definitions.getDrawable('url($xlinkHref)')); + print(el); + final DrawableStyle style = parseStyle( + el, + definitions, + rootBounds, + null, + needsTransform: true, + ); + print(style); + final DrawableStyleable ref = definitions.getDrawable('url($xlinkHref)'); + return DrawableGroup( + [ref.mergeStyle(style)], + style, + ); } unhandled(el); @@ -224,8 +298,13 @@ DrawableStyle parseStyle( DrawableStyle parentStyle, { bool needsTransform = false, }) { - final Matrix4 transform = - needsTransform ? parseTransform(getAttribute(el, 'transform')) : null; + final Matrix4 transform = needsTransform + ? parseTransform( + getAttribute(el, 'transform'), + getAttribute(el, 'x', def: null), + getAttribute(el, 'y', def: null), + ) + : null; return DrawableStyle.mergeAndBlend( parentStyle, diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 433976293ad8..7dd9fc961949 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -20,6 +20,18 @@ abstract class Drawable { void draw(Canvas canvas, ColorFilter colorFilter); } +@immutable +abstract class DrawableStyleable extends Drawable { + /// The [DrawableStyle] for this object. + DrawableStyle get style; + + /// Creates an instance with new style information. + DrawableStyleable replaceStyle(DrawableStyle newStyle); + + /// Creates an instance with merged style information. + DrawableStyleable mergeStyle(DrawableStyle newStyle); +} + /// Styling information for vector drawing. /// /// Contains [Paint], [Path], dashing, transform, and text styling information. @@ -417,6 +429,26 @@ class DrawableText implements Drawable { class DrawableDefinitionServer { final Map _paintServers = {}; final Map> _clipPaths = >{}; + final Map _drawables = + {}; + + /// Attempt to lookup a [Drawable] by [id]. + DrawableStyleable getDrawable(String id, {bool nullOk = false}) { + assert(id != null); + final DrawableStyleable value = _drawables[id]; + if (value == null && nullOk != true) { + throw StateError('Expected to find Drawable with id $id.\n' + 'Have ids: ${_drawables.keys}'); + } + return value; + } + + /// Add a [Drawable] that can later be referred to by [id]. + void addDrawable(String id, DrawableStyleable drawable) { + assert(id != null); + assert(drawable != null); + _drawables[id] = drawable; + } /// Attempt to lookup a pre-defined [Paint] by [id]. /// @@ -429,20 +461,29 @@ class DrawableDefinitionServer { return srv != null ? srv(bounds) : null; } + /// Add a [PaintServer] by [id]. void addPaintServer(String id, PaintServer server) { assert(id != null); + assert(server != null); _paintServers[id] = server; } + /// Get a [List] of clip paths by [id]. List getClipPath(String id) { assert(id != null); return _clipPaths[id]; } + /// Add a [List] of clip paths by [id]. void addClipPath(String id, List paths) { assert(id != null); + assert(paths != null); _clipPaths[id] = paths; } + + @override + String toString() => '$runtimeType{drawables: $_drawables, ' + 'paintServers: $_paintServers, clipPaths: $_clipPaths}'; } /// Contains the viewport size and offset for a Drawable. @@ -466,25 +507,6 @@ class DrawableViewport { /// A [Rect] representing the viewBox of this DrawableViewport. Rect get viewBoxRect => Offset.zero & viewBox; - /// Creates a [Rect] representing the viewport of this DrawableViewport. - /// - /// This [Rect] gets scaled by [devicePixelRatio] on non-infinite - /// dimensions of [Size] (infinite dimensions of size are treated as "100%"). - // Rect calculateViewportRect(double devicePixelRatio) { - // if (size == Size.infinite) { - // return viewBoxRect; - // } - // final Size viewportSize = Size( - // size.width == double.infinity - // ? viewBox.width - // : size.width * devicePixelRatio, - // size.height == double.infinity - // ? viewBox.height - // : size.height * devicePixelRatio, - // ); - // return Offset.zero & viewportSize; - // } - /// The viewBox size for the drawable. final Size viewBox; @@ -500,8 +522,8 @@ class DrawableViewport { double get height => size.height; @override - String toString() => - 'DrawableViewport{$size, viewBox: $viewBox, viewBoxOffset: $viewBoxOffset}'; + String toString() => 'DrawableViewport{$size, viewBox: $viewBox, ' + 'viewBoxOffset: $viewBoxOffset}'; } /// The root element of a drawable. @@ -521,9 +543,6 @@ class DrawableRoot implements Drawable { /// Contains reusable definitions such as gradients and clipPaths. final DrawableDefinitionServer definitions; - // /// Contains [Paint]s that are used by multiple children, e.g. - // /// gradient shaders that are referenced by an identifier. - // final Map paintServers; /// The [DrawableStyle] for inheritence. final DrawableStyle style; @@ -602,7 +621,7 @@ class DrawableRoot implements Drawable { /// Represents an element that is not rendered and has no chidlren, e.g. /// a descriptive element. -// TODO: tie some of this into semantics/accessibility +// TODO(dnfield): tie some of this into semantics/accessibility class DrawableNoop implements Drawable { const DrawableNoop(this.name); @@ -616,7 +635,7 @@ class DrawableNoop implements Drawable { } /// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. -class DrawableGroup implements Drawable { +class DrawableGroup implements DrawableStyleable { const DrawableGroup(this.children, this.style); final List children; @@ -664,10 +683,36 @@ class DrawableGroup implements Drawable { innerDraw(); } } + + @override + DrawableGroup replaceStyle(DrawableStyle newStyle) { + assert(newStyle != null); + return DrawableGroup(children, newStyle); + } + + @override + DrawableGroup mergeStyle(DrawableStyle newStyle) { + assert(newStyle != null); + return DrawableGroup( + children, + DrawableStyle.mergeAndBlend( + style, + fill: newStyle.fill, + stroke: newStyle.stroke, + clipPath: newStyle.clipPath, + dashArray: newStyle.dashArray, + dashOffset: newStyle.dashOffset, + groupOpacity: newStyle.groupOpacity, + pathFillType: newStyle.pathFillType, + textStyle: newStyle.textStyle, + transform: newStyle.transform, + ), + ); + } } /// Represents a drawing element that will be rendered to the canvas. -class DrawableShape implements Drawable { +class DrawableShape implements Drawable, DrawableStyleable { const DrawableShape(this.path, this.style) : assert(path != null), assert(style != null); @@ -680,7 +725,7 @@ class DrawableShape implements Drawable { // can't use bounds.isEmpty here because some paths give a 0 width or height // see https://skia.org/user/api/SkPath_Reference#SkPath_getBounds // can't rely on style because parent style may end up filling or stroking - // TODO: implement display properties - but that should really be done on style. + // TODO(dnfield): implement display properties - but that should really be done on style. @override bool get hasDrawableContent => bounds.width + bounds.height > 0; @@ -696,13 +741,11 @@ class DrawableShape implements Drawable { final Function innerDraw = () { if (style.fill?.style != null) { assert(style.fill.style == PaintingStyle.fill); - // style.fill.colorFilter = colorFilter; canvas.drawPath(path, style.fill.toFlutterPaint(colorFilter)); } if (style.stroke?.style != null) { assert(style.stroke.style == PaintingStyle.stroke); - // style.stroke.colorFilter = colorFilter; if (style.dashArray != null && !identical(style.dashArray, DrawableStyle.emptyDashArray)) { canvas.drawPath( @@ -726,4 +769,29 @@ class DrawableShape implements Drawable { innerDraw(); } } + + @override + DrawableShape replaceStyle(DrawableStyle newStyle) { + return DrawableShape(path, newStyle); + } + + @override + DrawableShape mergeStyle(DrawableStyle newStyle) { + assert(newStyle != null); + return DrawableShape( + path, + DrawableStyle.mergeAndBlend( + style, + fill: newStyle.fill, + stroke: newStyle.stroke, + clipPath: newStyle.clipPath, + dashArray: newStyle.dashArray, + dashOffset: newStyle.dashOffset, + groupOpacity: newStyle.groupOpacity, + pathFillType: newStyle.pathFillType, + textStyle: newStyle.textStyle, + transform: newStyle.transform, + ), + ); + } } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 4ce354e5be4b..f93ab8f463f0 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -82,7 +82,7 @@ class Svg { /// /// The [key] will be used for debugging purposes. FutureOr fromSvgBytes(Uint8List raw, String key) async { - // TODO - do utf decoding in another thread? + // TODO(dnfield): do utf decoding in another thread? // Might just have to live with potentially slow(ish) decoding, this is causing errors. // See: https://github.com/dart-lang/sdk/issues/31954 // See: https://github.com/flutter/flutter/blob/bf3bd7667f07709d0b817ebfcb6972782cfef637/packages/flutter/lib/src/services/asset_bundle.dart#L66 @@ -105,7 +105,6 @@ class Svg { DrawableRoot fromSvgString(String rawSvg, String key) { final XmlElement svg = xml.parse(rawSvg).rootElement; final DrawableViewport viewBox = parseViewBox(svg); - //final Map paintServers = {}; final DrawableDefinitionServer definitions = DrawableDefinitionServer(); final DrawableStyle style = parseStyle(svg, definitions, viewBox.viewBoxRect, null); @@ -122,6 +121,7 @@ class Svg { ), ) .toList(); + print(definitions); return DrawableRoot( viewBox, children, diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index 310dce8f1eab..423ffc854e7a 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -90,7 +90,7 @@ void main() { final XmlElement pct = parse('').rootElement; - // TODO: DashOffset is completely opaque right now, maybe expose the raw value? + // TODO(dnfield): DashOffset is completely opaque right now, maybe expose the raw value? expect(parseDashOffset(abs), isNotNull); expect(parseDashOffset(pct), isNotNull); }); From a4219acf9d6343db4e3b5b1f429330acfc71edaf Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 25 Nov 2018 16:17:35 -0800 Subject: [PATCH 171/512] partial for symbols --- third_party/example/lib/main.dart | 143 +++++++++++------------------- 1 file changed, 52 insertions(+), 91 deletions(-) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index f34ce2d2df05..dc833710dfbf 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -87,103 +87,64 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; - _painters.add(SvgPicture.string( - ''' - - - -''')); +// _painters.add(SvgPicture.string( +// ''' +// +// +// +// ''')); _painters.add( SvgPicture.string( - ''' - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + ''' + + + + + + + + + + + + + + ''', - color: Colors.black, ), ); - _painters.add(SvgPicture.string(''' - - - Close - Created with Sketch. - - - - - - - - - - -''')); - for (String assetName in assetNames) { - _painters.add( - SvgPicture.asset(assetName), - ); - } - - for (int i = 0; i < iconNames.length; i++) { - _painters.add( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.asset( - iconNames[i], - color: Colors.blueGrey[(i + 1) * 100], - matchTextDirection: true, - ), - ), - ); - } - - for (String uriName in uriNames) { - _painters.add( - SvgPicture.network( - uriName, - placeholderBuilder: (BuildContext context) => Container( - padding: const EdgeInsets.all(30.0), - child: const CircularProgressIndicator()), - ), - ); - } - _painters.add(AvdPicture.asset('assets/android_vd/battery_charging.xml')); + // for (String assetName in assetNames) { + // _painters.add( + // SvgPicture.asset(assetName), + // ); + // } + + // for (int i = 0; i < iconNames.length; i++) { + // _painters.add( + // Directionality( + // textDirection: TextDirection.ltr, + // child: SvgPicture.asset( + // iconNames[i], + // color: Colors.blueGrey[(i + 1) * 100], + // matchTextDirection: true, + // ), + // ), + // ); + // } + + // for (String uriName in uriNames) { + // _painters.add( + // SvgPicture.network( + // uriName, + // placeholderBuilder: (BuildContext context) => Container( + // padding: const EdgeInsets.all(30.0), + // child: const CircularProgressIndicator()), + // ), + // ); + // } + // _painters.add(AvdPicture.asset('assets/android_vd/battery_charging.xml')); } @override From 6133bd0cdcff9e427ef7c029cf4f0f30d2f18184 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 25 Nov 2018 22:58:11 -0800 Subject: [PATCH 172/512] initial impl for `use` --- .../example/assets/simple/use_circles.svg | 6 ++ .../assets/simple/use_opacity_grid.svg | 18 ++++ third_party/example/lib/main.dart | 86 ++++++------------ third_party/golden/simple/use_circles.png | Bin 0 -> 2496 bytes .../golden/simple/use_opacity_grid.png | Bin 0 -> 957 bytes third_party/lib/src/svg/parsers.dart | 7 +- third_party/lib/src/svg_parser.dart | 22 ++--- third_party/lib/src/vector_drawable.dart | 84 ++++++++++------- third_party/lib/svg.dart | 1 - third_party/tool/gen_golden.dart | 2 +- 10 files changed, 114 insertions(+), 112 deletions(-) create mode 100644 third_party/example/assets/simple/use_circles.svg create mode 100644 third_party/example/assets/simple/use_opacity_grid.svg create mode 100644 third_party/golden/simple/use_circles.png create mode 100644 third_party/golden/simple/use_opacity_grid.png diff --git a/third_party/example/assets/simple/use_circles.svg b/third_party/example/assets/simple/use_circles.svg new file mode 100644 index 000000000000..56b1e49614cf --- /dev/null +++ b/third_party/example/assets/simple/use_circles.svg @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/third_party/example/assets/simple/use_opacity_grid.svg b/third_party/example/assets/simple/use_opacity_grid.svg new file mode 100644 index 000000000000..eb6aa098eb59 --- /dev/null +++ b/third_party/example/assets/simple/use_opacity_grid.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index dc833710dfbf..f5c1de48b760 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -29,6 +29,8 @@ const List assetNames = [ 'assets/simple/dash_path.svg', 'assets/simple/nested_group.svg', 'assets/simple/stroke_inherit_circles.svg', + 'assets/simple/use_circles.svg', + 'assets/simple/use_opacity_grid.svg', 'assets/wikimedia/chess_knight.svg', 'assets/wikimedia/Ghostscript_Tiger.svg', 'assets/wikimedia/Firefox_Logo_2017.svg', @@ -87,64 +89,36 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; -// _painters.add(SvgPicture.string( -// ''' -// -// -// -// ''')); - _painters.add( - SvgPicture.string( - ''' - - - - - - - - - - - - - - -''', - ), - ); - - // for (String assetName in assetNames) { - // _painters.add( - // SvgPicture.asset(assetName), - // ); - // } + for (String assetName in assetNames) { + _painters.add( + SvgPicture.asset(assetName), + ); + } - // for (int i = 0; i < iconNames.length; i++) { - // _painters.add( - // Directionality( - // textDirection: TextDirection.ltr, - // child: SvgPicture.asset( - // iconNames[i], - // color: Colors.blueGrey[(i + 1) * 100], - // matchTextDirection: true, - // ), - // ), - // ); - // } + for (int i = 0; i < iconNames.length; i++) { + _painters.add( + Directionality( + textDirection: TextDirection.ltr, + child: SvgPicture.asset( + iconNames[i], + color: Colors.blueGrey[(i + 1) * 100], + matchTextDirection: true, + ), + ), + ); + } - // for (String uriName in uriNames) { - // _painters.add( - // SvgPicture.network( - // uriName, - // placeholderBuilder: (BuildContext context) => Container( - // padding: const EdgeInsets.all(30.0), - // child: const CircularProgressIndicator()), - // ), - // ); - // } - // _painters.add(AvdPicture.asset('assets/android_vd/battery_charging.xml')); + for (String uriName in uriNames) { + _painters.add( + SvgPicture.network( + uriName, + placeholderBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator()), + ), + ); + } + _painters.add(AvdPicture.asset('assets/android_vd/battery_charging.xml')); } @override diff --git a/third_party/golden/simple/use_circles.png b/third_party/golden/simple/use_circles.png new file mode 100644 index 0000000000000000000000000000000000000000..46c3aab5eab661e1b19a7054a1d49507b12e3fe6 GIT binary patch literal 2496 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 _matrixParsers = { /// transforms and use a Matrix4 rather than Matrix3 for the affine matrices. /// /// Also adds [x] and [y] to append as a final translation, e.g. for ``. -Matrix4 parseTransform(String transform, [String x, String y]) { - if (x != null || y != null) { - x ??= '0'; - y ??= '0'; - transform = '$transform translate($x $y)'; - } +Matrix4 parseTransform(String transform) { if (transform == null || transform == '') { return null; } diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 6e814ae1db41..58c0af8a1fe2 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -122,7 +122,7 @@ Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, if (iri != emptyUrlIri) { definitions.addDrawable(iri, group); } - return group; + return el.name.local == 'symbol' ? const DrawableNoop('symbol') : group; } else if (el.name.local == 'text') { return parseSvgText(el, definitions, rootBounds, parentStyle); } else if (el.name.local == 'svg') { @@ -134,20 +134,21 @@ Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, namespace: 'http://www.w3.org/1999/xlink', def: getAttribute(el, 'href'), ); - print(definitions.getDrawable('url($xlinkHref)')); - print(el); final DrawableStyle style = parseStyle( el, definitions, rootBounds, null, - needsTransform: true, ); - print(style); + final Matrix4 transform = Matrix4.identity() + ..translate( + double.parse(getAttribute(el, 'x', def: '0')), + double.parse(getAttribute(el, 'y', def: '0')), + ); final DrawableStyleable ref = definitions.getDrawable('url($xlinkHref)'); return DrawableGroup( [ref.mergeStyle(style)], - style, + DrawableStyle(transform: transform.storage), ); } @@ -298,13 +299,8 @@ DrawableStyle parseStyle( DrawableStyle parentStyle, { bool needsTransform = false, }) { - final Matrix4 transform = needsTransform - ? parseTransform( - getAttribute(el, 'transform'), - getAttribute(el, 'x', def: null), - getAttribute(el, 'y', def: null), - ) - : null; + final Matrix4 transform = + needsTransform ? parseTransform(getAttribute(el, 'transform')) : null; return DrawableStyle.mergeAndBlend( parentStyle, diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 7dd9fc961949..7cc00204ddcc 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -37,16 +37,17 @@ abstract class DrawableStyleable extends Drawable { /// Contains [Paint], [Path], dashing, transform, and text styling information. @immutable class DrawableStyle { - const DrawableStyle( - {this.stroke, - this.dashArray, - this.dashOffset, - this.fill, - this.transform, - this.textStyle, - this.pathFillType, - this.groupOpacity, - this.clipPath}); + const DrawableStyle({ + this.stroke, + this.dashArray, + this.dashOffset, + this.fill, + this.transform, + this.textStyle, + this.pathFillType, + this.groupOpacity, + this.clipPath, + }); /// Used where 'dasharray' is 'none' /// @@ -85,16 +86,18 @@ class DrawableStyle { /// Creates a new [DrawableStyle] if `parent` is not null, filling in any null properties on /// this with the properties from other (except [groupOpacity], which is averaged). - static DrawableStyle mergeAndBlend(DrawableStyle parent, - {DrawablePaint fill, - DrawablePaint stroke, - CircularIntervalList dashArray, - DashOffset dashOffset, - Float64List transform, - DrawableTextStyle textStyle, - PathFillType pathFillType, - double groupOpacity, - List clipPath}) { + static DrawableStyle mergeAndBlend( + DrawableStyle parent, { + DrawablePaint fill, + DrawablePaint stroke, + CircularIntervalList dashArray, + DashOffset dashOffset, + Float64List transform, + DrawableTextStyle textStyle, + PathFillType pathFillType, + double groupOpacity, + List clipPath, + }) { groupOpacity = mergeOpacity(groupOpacity, parent?.groupOpacity); return DrawableStyle( fill: DrawablePaint.merge(fill, parent?.fill, groupOpacity), @@ -639,6 +642,7 @@ class DrawableGroup implements DrawableStyleable { const DrawableGroup(this.children, this.style); final List children; + @override final DrawableStyle style; @override @@ -693,20 +697,26 @@ class DrawableGroup implements DrawableStyleable { @override DrawableGroup mergeStyle(DrawableStyle newStyle) { assert(newStyle != null); + final DrawableStyle mergedStyle = DrawableStyle.mergeAndBlend( + style, + fill: newStyle.fill, + stroke: newStyle.stroke, + clipPath: newStyle.clipPath, + dashArray: newStyle.dashArray, + dashOffset: newStyle.dashOffset, + groupOpacity: newStyle.groupOpacity, + pathFillType: newStyle.pathFillType, + textStyle: newStyle.textStyle, + transform: newStyle.transform, + ); return DrawableGroup( - children, - DrawableStyle.mergeAndBlend( - style, - fill: newStyle.fill, - stroke: newStyle.stroke, - clipPath: newStyle.clipPath, - dashArray: newStyle.dashArray, - dashOffset: newStyle.dashOffset, - groupOpacity: newStyle.groupOpacity, - pathFillType: newStyle.pathFillType, - textStyle: newStyle.textStyle, - transform: newStyle.transform, - ), + children.map((Drawable child) { + if (child is DrawableStyleable) { + return child.mergeStyle(mergedStyle); + } + return child; + }).toList(), + mergedStyle, ); } } @@ -717,6 +727,7 @@ class DrawableShape implements Drawable, DrawableStyleable { : assert(path != null), assert(style != null); + @override final DrawableStyle style; final Path path; @@ -749,8 +760,11 @@ class DrawableShape implements Drawable, DrawableStyleable { if (style.dashArray != null && !identical(style.dashArray, DrawableStyle.emptyDashArray)) { canvas.drawPath( - dashPath(path, - dashArray: style.dashArray, dashOffset: style.dashOffset), + dashPath( + path, + dashArray: style.dashArray, + dashOffset: style.dashOffset, + ), style.stroke.toFlutterPaint(colorFilter)); } else { canvas.drawPath(path, style.stroke.toFlutterPaint(colorFilter)); diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index f93ab8f463f0..6243aa779034 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -121,7 +121,6 @@ class Svg { ), ) .toList(); - print(definitions); return DrawableRoot( viewBox, children, diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index 7b544ea8e7ca..a9d876873fd7 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -68,7 +68,7 @@ Future main() async { goldenDir.createSync(recursive: true); } final File output = File(pathName); -print(pathName); + print(pathName); await output.writeAsBytes(await getSvgPngBytes(await fe.readAsString())); } } From 05d5f811580555fd4fdce5a61e24bcd38acddcb1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 25 Nov 2018 23:36:15 -0800 Subject: [PATCH 173/512] add some tests, minor fixes --- third_party/lib/src/picture_cache.dart | 2 +- third_party/lib/src/picture_stream.dart | 7 +--- third_party/test/picture_cache_test.dart | 32 ++++++++++++++ third_party/test/picture_stream_test.dart | 51 +++++++++++++++++++++++ 4 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 third_party/test/picture_cache_test.dart create mode 100644 third_party/test/picture_stream_test.dart diff --git a/third_party/lib/src/picture_cache.dart b/third_party/lib/src/picture_cache.dart index 06e8e6c3ea42..e1c99446b237 100644 --- a/third_party/lib/src/picture_cache.dart +++ b/third_party/lib/src/picture_cache.dart @@ -46,7 +46,7 @@ class PictureCache { _cache.clear(); } - /// Returns the previously cached [ImageStream] for the given key, if available; + /// Returns the previously cached [PictureStream] for the given key, if available; /// if not, calls the given callback to obtain it first. In either case, the /// key is moved to the "most recently used" position. /// diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart index 687db8d2ba33..57a70aaceaff 100644 --- a/third_party/lib/src/picture_stream.dart +++ b/third_party/lib/src/picture_stream.dart @@ -35,10 +35,7 @@ class PictureInfo { final Size size; @override - String toString() => '$picture'; - - @override - int get hashCode => hashValues(picture, viewport); + int get hashCode => hashValues(picture, viewport, size); @override bool operator ==(Object other) { @@ -46,7 +43,7 @@ class PictureInfo { return false; } final PictureInfo typedOther = other; - return typedOther.picture == picture && typedOther.viewport == viewport; + return typedOther.picture == picture && typedOther.viewport == viewport && typedOther.size == size; } } diff --git a/third_party/test/picture_cache_test.dart b/third_party/test/picture_cache_test.dart new file mode 100644 index 000000000000..8691d6d527ca --- /dev/null +++ b/third_party/test/picture_cache_test.dart @@ -0,0 +1,32 @@ +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_svg/src/picture_cache.dart'; +import 'package:test/test.dart'; + +class MockPictureStreamCompleter extends PictureStreamCompleter {} + +void main() { + final PictureCache cache = PictureCache(); + test('Cache Tests', () { + expect(cache.maximumSize, equals(1000)); + cache.maximumSize = 1; + expect(cache.maximumSize, equals(1)); + + expect(() => cache.maximumSize = -1, + throwsA(const TypeMatcher())); + expect(() => cache.maximumSize = null, + throwsA(const TypeMatcher())); + + expect(() => cache.putIfAbsent(null, null), + throwsA(const TypeMatcher())); + expect(() => cache.putIfAbsent(1, null), + throwsA(const TypeMatcher())); + + final MockPictureStreamCompleter completer1 = MockPictureStreamCompleter(); + final MockPictureStreamCompleter completer2 = MockPictureStreamCompleter(); + expect(cache.putIfAbsent(1, () => completer1), completer1); + expect(cache.putIfAbsent(1, () => completer1), completer1); + expect(cache.putIfAbsent(2, () => completer2), completer2); + + cache.clear(); + }); +} diff --git a/third_party/test/picture_stream_test.dart b/third_party/test/picture_stream_test.dart new file mode 100644 index 000000000000..f0d16aa7e5ef --- /dev/null +++ b/third_party/test/picture_stream_test.dart @@ -0,0 +1,51 @@ +import 'dart:ui'; + +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:test/test.dart'; + +void main() { + test('PictureInfo Tests', () { + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + canvas.drawPaint(Paint()..color = const Color(0xFFFA0000)); + final Picture picture = recorder.endRecording(); + + expect( + // ignore: prefer_const_constructors + () => PictureInfo( + picture: null, + viewport: null, + size: null, + ), + throwsA(const TypeMatcher())); + + expect( + () => PictureInfo( + picture: null, + viewport: Rect.zero, + size: null, + ), + throwsA(const TypeMatcher())); + expect( + () => PictureInfo( + picture: null, + viewport: Rect.zero, + size: Size.zero, + ), + throwsA(const TypeMatcher())); + + final PictureInfo info1 = PictureInfo( + picture: picture, + viewport: Rect.zero, + size: Size.zero, + ); + + final PictureInfo info2 = PictureInfo( + picture: picture, + viewport: Rect.zero, + size: Size.zero, + ); + expect(info1.hashCode, equals(info2.hashCode)); + expect(info1, equals(info2)); + }); +} From b9875f1d38ed18a0c2f77f7155124e5403db2f7b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 26 Nov 2018 00:07:49 -0800 Subject: [PATCH 174/512] include text test --- third_party/golden/simple/text.png | Bin 0 -> 518 bytes third_party/tool/gen_golden.dart | 11 ++--------- 2 files changed, 2 insertions(+), 9 deletions(-) create mode 100644 third_party/golden/simple/text.png diff --git a/third_party/golden/simple/text.png b/third_party/golden/simple/text.png new file mode 100644 index 0000000000000000000000000000000000000000..8bbb9407cd6dce96785461b0ab56534a5f331cf8 GIT binary patch literal 518 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>pxg#e7srr_IdAVM`W*=nX}cJ`LbhGyC10APvcMXS<9cc094@NT4jUL;v~M03 zY5X5-_%ge#_=~W)`Fn4zxF}YjiKK%AUrV2V-o)el+AyJh*~(S&ZL2P?{Hn3R{&7U< z^(u}V#*GdN0vs$%q*Ar78UL-G{(Sv4s#Wn#3yIx8sjYU%N->D%w!JpSBKVXckb+WiuLZdRr9f4AGH zAVh}SfS$SFAAHqfn;i4E^m)<#qz4*EN5Sek#ux`ho0L@HRUp2ntDnm{r-UW|l-G!v literal 0 HcmV?d00001 diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index 7b544ea8e7ca..8b2c4912a9c2 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -36,17 +36,10 @@ Future getSvgPngBytes(String svgData) async { return bytes.buffer.asUint8List(); } -final Set badSvgFiles = Set.of([ - 'simple/text.svg', -]); - Iterable getSvgFileNames() sync* { final Directory dir = Directory('./example/assets'); for (FileSystemEntity fe in dir.listSync(recursive: true)) { - if (fe is File && - fe.path.toLowerCase().endsWith('.svg') && - !badSvgFiles.contains(fe.path - .substring(fe.path.lastIndexOf(RegExp(r'[\\/]assets')) + 8))) { + if (fe is File && fe.path.toLowerCase().endsWith('.svg')) { yield fe; } } @@ -68,7 +61,7 @@ Future main() async { goldenDir.createSync(recursive: true); } final File output = File(pathName); -print(pathName); + print(pathName); await output.writeAsBytes(await getSvgPngBytes(await fe.readAsString())); } } From 3cd119e32b5eb22e724e8ad356bb64cf8d6c1ba6 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 26 Nov 2018 00:15:35 -0800 Subject: [PATCH 175/512] linux gen text --- third_party/golden/simple/text.png | Bin 518 -> 451 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/third_party/golden/simple/text.png b/third_party/golden/simple/text.png index 8bbb9407cd6dce96785461b0ab56534a5f331cf8..fbf7a2c3bfdbeab73501a8b1f051c995aef51768 100644 GIT binary patch literal 451 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>pj@t}i(^Q|oVRy3W*&B6XuBAELGIQu=PKd#%KVE&)?KRUJouyKbKKfT&mTCS zRqSO1nm{@@@LKo!>%yGdZzK!se%l?}m75%+w|V)2pLg<-YtG6srmG2XFf}TWNW6Z- z`2XsrGjRoc$3K2gPoFc>oP(v&K>!O;a5ZI8`nre@AKn>%ZrA+L>Y%{E(nKVJUX<4B-HR z8jh3>pxg#e7srr_IdAVM`W*=nX}cJ`LbhGyC10APvcMXS<9cc094@NT4jUL;v~M03 zY5X5-_%ge#_=~W)`Fn4zxF}YjiKK%AUrV2V-o)el+AyJh*~(S&ZL2P?{Hn3R{&7U< z^(u}V#*GdN0vs$%q*Ar78UL-G{(Sv4s#Wn#3yIx8sjYU%N->D%w!JpSBKVXckb+WiuLZdRr9f4AGH zAVh}SfS$SFAAHqfn;i4E^m)<#qz4*EN5Sek#ux`ho0L@HRUp2ntDnm{r-UW|l-G!v From fc8fc118fcbebf319255271ae0b823fa6c1e2192 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 26 Nov 2018 12:57:42 -0800 Subject: [PATCH 176/512] more test, format, remove temp code from example --- third_party/example/lib/main.dart | 36 ----------------- third_party/lib/src/picture_stream.dart | 4 +- third_party/lib/src/svg/parsers.dart | 5 ++- ...er_svg_test.dart => svg_parsers_test.dart} | 40 ++++++++++++++++++- third_party/test/xml_svg_test.dart | 3 ++ 5 files changed, 47 insertions(+), 41 deletions(-) rename third_party/test/{parser_svg_test.dart => svg_parsers_test.dart} (53%) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index 05829c0bd275..c156d7ea5e3f 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -88,42 +88,6 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; - _painters.add( - SvgPicture.string( - ''' - - - Fill 1 - Created with Sketch. - - - - - - - - -''', - color: Colors.black, - ), - ); - - _painters.add(SvgPicture.string(''' - - - Close - Created with Sketch. - - - - - - - - - - -''')); for (String assetName in assetNames) { _painters.add( SvgPicture.asset(assetName), diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart index 57a70aaceaff..0fe814c15230 100644 --- a/third_party/lib/src/picture_stream.dart +++ b/third_party/lib/src/picture_stream.dart @@ -43,7 +43,9 @@ class PictureInfo { return false; } final PictureInfo typedOther = other; - return typedOther.picture == picture && typedOther.viewport == viewport && typedOther.size == size; + return typedOther.picture == picture && + typedOther.viewport == viewport && + typedOther.size == size; } } diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index 092c779ba087..237d9c417aa3 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -49,12 +49,13 @@ double parseFontSize(String raw, {double parentValue}) { DrawableTextAnchorPosition parseTextAnchor(String raw) { switch (raw) { + case 'inherit': + return null; case 'middle': return DrawableTextAnchorPosition.middle; - case 'start': - return DrawableTextAnchorPosition.start; case 'end': return DrawableTextAnchorPosition.end; + case 'start': default: return DrawableTextAnchorPosition.start; } diff --git a/third_party/test/parser_svg_test.dart b/third_party/test/svg_parsers_test.dart similarity index 53% rename from third_party/test/parser_svg_test.dart rename to third_party/test/svg_parsers_test.dart index bbe768b37478..53e62f73beb0 100644 --- a/third_party/test/parser_svg_test.dart +++ b/third_party/test/svg_parsers_test.dart @@ -1,11 +1,12 @@ -import 'dart:ui' show PathFillType; +import 'dart:ui' show PathFillType, window; import 'package:flutter_svg/src/svg/parsers.dart'; +import 'package:flutter_svg/src/vector_drawable.dart'; import 'package:test/test.dart'; import 'package:vector_math/vector_math_64.dart'; void main() { - test('SVG value parser tests', () { + test('SVG Transform parser tests', () { expect(() => parseTransform('invalid'), throwsStateError); expect(() => parseTransform('transformunsupported(0,0)'), throwsStateError); @@ -55,7 +56,9 @@ void main() { 0.0, 1.0 ])); + }); + test('FillRule tests', () { expect(parseRawFillRule(''), PathFillType.nonZero); expect(parseRawFillRule(null), isNull); expect(parseRawFillRule('inherit'), isNull); @@ -63,4 +66,37 @@ void main() { expect(parseRawFillRule('evenodd'), PathFillType.evenOdd); expect(parseRawFillRule('invalid'), PathFillType.nonZero); }); + + test('TextAnchor tests', () { + expect(parseTextAnchor(''), DrawableTextAnchorPosition.start); + expect(parseTextAnchor(null), DrawableTextAnchorPosition.start); + expect(parseTextAnchor('inherit'), isNull); + expect(parseTextAnchor('start'), DrawableTextAnchorPosition.start); + expect(parseTextAnchor('middle'), DrawableTextAnchorPosition.middle); + expect(parseTextAnchor('end'), DrawableTextAnchorPosition.end); + }); + + test('Font size parsing tests', () { + expect(parseFontSize(null), isNull); + expect(parseFontSize(''), isNull); + expect(parseFontSize('1'), 1); + expect(parseFontSize(' 1 '), 1); + expect(parseFontSize('xx-small'), 10 * window.devicePixelRatio); + expect(parseFontSize('x-small'), 12 * window.devicePixelRatio); + expect(parseFontSize('small'), 14 * window.devicePixelRatio); + expect(parseFontSize('medium'), 18 * window.devicePixelRatio); + expect(parseFontSize('large'), 22 * window.devicePixelRatio); + expect(parseFontSize('x-large'), 26 * window.devicePixelRatio); + expect(parseFontSize('xx-large'), 32 * window.devicePixelRatio); + + expect(parseFontSize('larger'), parseFontSize('large')); + expect(parseFontSize('larger', parentValue: parseFontSize('large')), + parseFontSize('large') * 1.2); + expect(parseFontSize('smaller'), parseFontSize('small')); + expect(parseFontSize('smaller', parentValue: parseFontSize('large')), + parseFontSize('large') / 1.2); + + expect(() => parseFontSize('invalid'), + throwsA(const TypeMatcher())); + }); } diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index 310dce8f1eab..deb77d6f96ba 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -18,6 +18,9 @@ void main() { expect(getAttribute(el, 'stroke-opacity'), '1'); expect(getAttribute(el, 'stroke-another'), ''); expect(getAttribute(el, 'fill-opacity'), '.23'); + + expect(getAttribute(el, 'fill-opacity', checkStyle: false), ''); + expect(getAttribute(el, 'fill', checkStyle: false), '#eee'); }); // if the parsing logic changes, we can simplify some methods. for now assert that whitespace in attributes is preserved test('Attribute WhiteSpace test', () { From df768579afb7ec45976aeb7679a12420b182bb98 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 26 Nov 2018 13:40:58 -0800 Subject: [PATCH 177/512] support symbol in or out of def --- .../example/assets/simple/use_emc2.svg | 40 ++++++++++++++++++ .../assets/simple/use_opacity_grid.svg | 2 +- third_party/golden/simple/use_emc2.png | Bin 0 -> 2494 bytes third_party/lib/src/svg_parser.dart | 16 +++++-- 4 files changed, 54 insertions(+), 4 deletions(-) create mode 100644 third_party/example/assets/simple/use_emc2.svg create mode 100644 third_party/golden/simple/use_emc2.png diff --git a/third_party/example/assets/simple/use_emc2.svg b/third_party/example/assets/simple/use_emc2.svg new file mode 100644 index 000000000000..8a3982f780e9 --- /dev/null +++ b/third_party/example/assets/simple/use_emc2.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/third_party/example/assets/simple/use_opacity_grid.svg b/third_party/example/assets/simple/use_opacity_grid.svg index eb6aa098eb59..cee08c158a81 100644 --- a/third_party/example/assets/simple/use_opacity_grid.svg +++ b/third_party/example/assets/simple/use_opacity_grid.svg @@ -3,7 +3,7 @@ - + diff --git a/third_party/golden/simple/use_emc2.png b/third_party/golden/simple/use_emc2.png new file mode 100644 index 0000000000000000000000000000000000000000..d2e21eca782e6d80c473d3861ce618c3c110ba9e GIT binary patch literal 2494 zcmb_ejX%@dAE%UE$y2VR-P$k0MaZRGX-j#UXCqQbuE!0x>3T>WihIjb2wRuTZp!3w zKW3B7EJ?B{Wo&n58_ilQ{3J&6aKHWjhWmNF&iS0rd7anibI#|y-=A{|{CwQ@su`#$ zDJkuRyE`KQ{pwo-?FRbR3vIQ4Qoe?8JFC?820RNGD%Z}!13`dff}--3l)j6DJ39rY z*USs1Q<{eLZcgK93ps0MHv?|fsM&u1vGGhRgs`JMH*Qy%+6!Rfj2Wm=3DGxsSd?1? zasauOUdNL=IB*RuUCK|SSWRtZAi}>d8-hcX2tEq0aa=oeK zrUiMXy-i>JPU(IpFTtp=j*j2Ed*`fNaZ#}k^3=0v;4GF^Z(9EX4c69%vjc@9k&E*S zN@A6lu?>Et^su{fT8y>6X}|SY1|7P_C@s|-UzB6=O||_?#7~Ui$WoW;{b|uB9>BF! zbX@NJNeH0{;%v)b#~2wqasx{cY@pZ*~8>-&Vgv5{KuJu~A z$tW<|?ys9r<=i*lt1kKa`jU^iH&=bJR>wq#thYSQ|CX3k+Bnp;+z3e%n2jutr8^2w zVe@Sr^#1B!?%CLylPlc162p*)8p?icyF;ayey~zM7p?D_-2)ty(g2!yZXHO7|ImkS z8Fp^ODwi7#^_gU!-}DR^0I5KX#g&p~NZK<+_h0osk8&Xv(2IPf0R-FKwdClq9l zWxZHS7v~ImEoY`kLy(a*RcTr{v$W)2i6HZu99m;WMMB|fFYG*o6Byig8*jcxgVh0G zfH~#P4%91hk!;1Px>pl0=49%a(dexX3wyxTr&QX+Y_4e`vcc+&Mp?4l<1zo>SDCCx zPbHR>`-?r8nbdVE!)hK_WtkPL92tUL{aqN@{&#a;BZ3Rw(Gb;l96#cVt$iGCMkEr+ z@&%r9^1_;7$uF(EHDhJfsE%*3Yw>u=^z`&cE^K?l5Dn%EQL)kO6UDGx$XjOW06Ozc z<7ONh%u*<5e-av3l=ls`XJ%)6=(+&7xqz(~AQ^PJh~THQKr(hzF5{qU4Hk)JB#rGlBp!N*ukR!$5lMAB2as9;j&Gf#Aj7Nz5RD2ZIG zJfZ87oxb{KQGk#*wDJ5ny!?qIxeEWwx}!HcuuXR8(@C&~=7OhyNL9#Nl&VIgH&nT} zw>Pd|k9YLXV|Qq_e9H1JH)5boD&W0gMq)UP!(wDa;>=s#EXxTVCJz zn7zE-GmZ+eynmw}a=womP6S|tv^5}q4Rd&-Rz_F}hL@XiQyPg>Ej~pvY52XJTE8_O z4oz)^LZP3t68J$Lo3JMtbm2R*g2;DsKXXqiPV%QB?Z@v-h;5)Mq7w035{#Lcq_lz3<|vf0x~nPX9RGGIV4^n6iWJ=c?nxj z*Cju_3?9_E{gCtf{LfW}+B}xSN(Q|mKuIFwMx#O-y}JkR%=fZ zjNX&^5bo(WY(J|p#u_?=8$bgr7I896Q(i*oYq`}u>;2Py2X4PxQ}MTAeW=9z>KG<@ zrq=I=V!WRUH?xUwP<+WaJ-<9$t|5B(&MV`*+_|g3ll`Sh(0s$z;I0|1Yd|&@#XEy$ z7+2&-6lY@@$-zxSe+khwznY&zeh=~HlIaYHJB3;<8(igtlGuEdL4C$I&;UqaVy*wPo`0qgEe=3G%Vqo4| zyTgiM&eglzUAz8nuhHq1D7{N^vh3apoe^;iOT?~uWWoa4nBG#fleeonvS@9FbngW!~1Kf|$S~zm_Ie_mesc0qp zHz(Sz?wOqiz_aoKZBZ*tNgXx=>VHxfZQ|lSz{3PC?x!u&)Em@K;jKZ2V+DK0EvWM> zhH+#m!bLmvMvy=fLa$fT_|In)v(qcSOp ztuS*xM^}y@8SK{G)|@E{Zj&|f60lbN^KwP-b!?vyAJLpqGg2@3Y%wP?0_^}Qkd3~& z!BNMK!6bm_ZL$+Sy})JlF0zukSnO`8#jU-$5ybmfstNWb6%8+mWG{u&k12wqssH}x d<^LY{FT+MQeYpJ*Z(n}1;VwSTZD%8L{{efMy|MrR literal 0 HcmV?d00001 diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 58c0af8a1fe2..36d9032904c8 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -55,8 +55,15 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [Drawable] from an SVG or shape element. Also handles parsing and gradients. /// /// If an unsupported element is encountered, it will be created as a [DrawableNoop]. -Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, - Rect rootBounds, DrawableStyle parentStyle, String key) { +Drawable parseSvgElement( + XmlElement el, + DrawableDefinitionServer definitions, + Rect rootBounds, + DrawableStyle parentStyle, + String key, { + bool isDef = false, +}) { + assert(isDef != null); final Function unhandled = (XmlElement e) => _unhandledElement(e, key); final Function createDefinition = (String iri, XmlElement defEl) { assert(iri != emptyUrlIri); @@ -68,6 +75,7 @@ Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, rootBounds, parentStyle, key, + isDef: true, ), ); }; @@ -122,7 +130,9 @@ Drawable parseSvgElement(XmlElement el, DrawableDefinitionServer definitions, if (iri != emptyUrlIri) { definitions.addDrawable(iri, group); } - return el.name.local == 'symbol' ? const DrawableNoop('symbol') : group; + return el.name.local == 'symbol' && !isDef + ? const DrawableNoop('symbol') + : group; } else if (el.name.local == 'text') { return parseSvgText(el, definitions, rootBounds, parentStyle); } else if (el.name.local == 'svg') { From b78e2071717165bbdb61673439710200df198de2 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 26 Nov 2018 14:09:57 -0800 Subject: [PATCH 178/512] test def with id --- .../example/assets/simple/use_circles_def.svg | 8 ++++++++ third_party/golden/simple/use_circles_def.png | Bin 0 -> 1975 bytes 2 files changed, 8 insertions(+) create mode 100644 third_party/example/assets/simple/use_circles_def.svg create mode 100644 third_party/golden/simple/use_circles_def.png diff --git a/third_party/example/assets/simple/use_circles_def.svg b/third_party/example/assets/simple/use_circles_def.svg new file mode 100644 index 000000000000..ffabbf0650c7 --- /dev/null +++ b/third_party/example/assets/simple/use_circles_def.svg @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/third_party/golden/simple/use_circles_def.png b/third_party/golden/simple/use_circles_def.png new file mode 100644 index 0000000000000000000000000000000000000000..c2315e8154f0e846b7fbfec242d718fc4dc6b9e6 GIT binary patch literal 1975 zcmb_d`!^E|AKzH65vh2KHanF2+bhqKM;XoQE|)Z>5pBZ^t%wQp_CzDsgv{f9c@u`1 zVMR|Wix#3Lb9sm-wpeCj#=PtO8=lWO-|zQ)e))XP`JVIrelol~ozzs0ssI20H5X@u zk8HAjmXd<3H~Z7dWdnHA$H@Ued#}4JBcPiOE|-*KNK(R3006}h7li$#gx^=D=ZKTG zx&v$E3jXce@>9xJ<%RAVHb9Kr5-3mkL6{s1G@|TqBGnyG_F@&37_^l1*4xaj(~K*U zbgvt7tRQE1%sv+xYRVk`Hf#kZdAnwFEkGlF!4G|&tT+JB8yC6z06kf$0EJ+#1wb0~ zwVlN+l~QA%(19A~qGf?#Rm8DA@{erM=H@1N_DuFo4N#nI=FX1sQ|_{$(eI|y8lLyZw0+k)B=@1! zOiL`V(^Cls7a5F(tdVL(%X9V|MpR8c>sFv3)d7A~B&^QGcx*7g_;2$6JBACI^()Fq z+LMlAo90pR!jai?4f`QiXj0;`Y6x9*G2n5JYs zIUny*WaE`H6-WjF#qLDqxJ965rcHhY>q8DVaaPDn=rh6K$){R#iyww1TQ{s9U3g&d z*X&8i;k(b2mm*CikO}Lucg+K_sJ(MkuUqibdbUcGn)98)Ra7`hA4N5A6byM)5nz1E*xf}*M=43&-HW-JwVub z`7JCiZugz0a{ge%tk}-}>HC24yXR_Od_2`1ixo*mh&>!0q6hLB$lZFoyqbc=e$ z$`b{NSmh{7&5UZk9rKgxK@HV_%Q2Z$n%GwGP|dfvDF&!%9PLQkEmNkX1*$l`uk&>L z3jR{=c{@6B=ZElxJ=`lm`(#$@+>IFo+-$t$Ze=5ZkKtveQKhGAhjty{S7Yx_yA>DZ zruuiKNx;QP;|&M2CeYXLVv9{xpxA9=V@KagF0`t}$yEysT#g*V^I$>JW@V+U=rzRD z;&BaN+X!Rs5KJbDkBD9aNrkC!nPu=jX{iPAG?j5D@EfjcykRMaROV90#o)zC&ijZ> zVS0UszqD~(dX}M%V5hU%`+m(_3ibO`9Cn=0rG6?_4?2ToqKTaElPUU;qHSwDo$_-% zeKFH!W8wk2JP_FS&|rJHyZ6}sDFOc#agD?hPi23sC16U#0XnEWYIIepA6>ov^1@o% zWMn#y8e4O{YCO-kMO4PVRD_=4y+gn5urn%bQJz2!4}ZM($RLAc{t9f@lN^kpn@CHD z^BJvYd(|w4QsS`3_VYNBSW8A_lsOQY-ryw9|01ffXf!Di5rz0M!XvDrx|~mb1dT(B zI)AdT^XvispqRqG)P^`%sjl*t+mkHJA@gd*FCu)&78jUbVwoqUm%H z)y;X{AH2-(G>YII*`JS(?9|FrXySx0ul)9(K8dcMp8BeJ_=Ba(*gnSX+%cDiuVK%V z+J__v?+sN2v&ykb_P;T0MnSE0G@}pwPCb?s%OO$a8=DJ%7Ay>pzKO$iW%wq8%lcc?# zu+t?hwo?TUfRWWF3a;NQ)YN#9>J$x>my^>;I-F0IrOn@#Uq6MyxqGht)!p|#qxnCn Ni=!uk=5Y1S{{Ru)lpO#7 literal 0 HcmV?d00001 From e65aa1519fc7537f514566c73d16ed4668333854 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 26 Nov 2018 15:45:07 -0800 Subject: [PATCH 179/512] update changelog/readme --- third_party/CHANGELOG.md | 63 +++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 24 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 870391e53395..e256696bb0d4 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -3,14 +3,18 @@ ## 0.7.0 - **BREAKING** Correct erroneous `width` and `height` processing on the root element. - - Previously, `width` and `height` were treated as synonyms for the width and height of the `viewBox`. - This is not correct, and resulted in meaningful rendering errors in some scenarios compared to - Chrome. Fixing this makes the parser more conformant to the spec, but may make your SVGs look significantly - different if they specify `width` or `height`. - If you want the old behavior, you'll have to update your SVGs to not specify `width` and `height` (only - specify `viewBox`). -- Use `MediaQuery.of(context).devicePixelRatio` if available before defaulting to `window.devicePixelRatio` - in places that need awareness of devicePixelRatios. + - Previously, `width` and `height` were treated as synonyms for the width and + height of the `viewBox`. This is not correct, and resulted in meaningful + rendering errors in some scenarios compared to Chrome. Fixing this makes the + parser more conformant to the spec, but may make your SVGs look + significantly different if they specify `width` or `height`. If you want the + old behavior, you'll have to update your SVGs to not specify `width` and + `height` (only specify `viewBox`). +- Use `MediaQuery.of(context).devicePixelRatio` if available before defaulting + to `window.devicePixelRatio` in places that need awareness of + devicePixelRatios. +- Support for ``, ``, and shape/group elements in ``. There + are some limitations to this currently, ## 0.6.3 @@ -19,7 +23,8 @@ ## 0.6.2 -- Consume updated version of path_drawing, which fixes https://github.com/dnfield/flutter_svg/issues/73 +- Consume updated version of path_drawing, which fixes + https://github.com/dnfield/flutter_svg/issues/73 ## 0.6.1 @@ -30,20 +35,24 @@ - **BREAKING** Update Flutter version dependencies/package dependencies - Print unhandled errors only once, and only in debug mode (000e17f) -- Add ability to specify a `BoxFit` and `Alignment` for SvgPictures (Thanks @sroddy!). +- Add ability to specify a `BoxFit` and `Alignment` for SvgPictures (Thanks + @sroddy!). - Support `userSpaceOnUse` gradientUnits (@sroddy) - Miscellaneous bug fixes - Restructure project to match expectations of Flutter tooling ## 0.5.5 -- Create a new class to encapsulate `Paint` and assist with inheriting all painting properties. -- Fixes regression introduced in v0.5.2 where some previously working inheritence stopped working. +- Create a new class to encapsulate `Paint` and assist with inheriting all + painting properties. +- Fixes regression introduced in v0.5.2 where some previously working + inheritence stopped working. - Support more complex stroke/fill property inheritence. ## 0.5.4 -- Consume latest path_drawing (and path_parsing) packages to fix issue(s) with smooth curve handling. +- Consume latest path_drawing (and path_parsing) packages to fix issue(s) with + smooth curve handling. ## 0.5.3 @@ -51,7 +60,8 @@ ## 0.5.2 -- Fix bug(s) in processing stroke and fill opacity when stroke/fill are inherited. +- Fix bug(s) in processing stroke and fill opacity when stroke/fill are + inherited. - Fix HTTP network headers for network pictures ## 0.5.1 @@ -89,7 +99,8 @@ ## 0.3.2 -- Bug fix around caching for tinting/coloring (color was not being properly included in cache keys) +- Bug fix around caching for tinting/coloring (color was not being properly + included in cache keys) ## 0.3.1 @@ -99,16 +110,18 @@ ## 0.3.0 - This version represents a major rewrite of the widget(s) involved in rendering - SVG drawings. This is primarily to support caching and better performance in rendering. -- New method on DrawableRoot toPicture to create a ui.Picture object from the SVG. -- Support for caching of Pictures, similar to how framework caches images. This will - eventually be configurable, but is not as of this release. + SVG drawings. This is primarily to support caching and better performance in + rendering. +- New method on DrawableRoot toPicture to create a ui.Picture object from the + SVG. +- Support for caching of Pictures, similar to how framework caches images. This + will eventually be configurable, but is not as of this release. ### BREAKING CHANGES - BREAKING CHANGE: `SvgImage`, `AvdImage`, and `VectorDrawableImage` have been - deprecated. They relied on methods that are less efficient than those - now surfaced in `SvgPicture`. + deprecated. They relied on methods that are less efficient than those now + surfaced in `SvgPicture`. - BREAKING CHANGE: Size is no longer passed to `SvgPicture` - its size is determined by parent size. - BREAKING CHANGE: `clipToViewBox` is now called `allowDrawingOutsideViewBox`. @@ -116,7 +129,7 @@ unexpected memory usage if your vector graphic tries to draw far outside of the viewBox bounds. - BREAKING CHANGE: `SvgPicture` does not support custom `ErrorWidgetBuilder`s at - this point in time. However, errors will be properly logged to the console. + this point in time. However, errors will be properly logged to the console. This is a result of improvements in the loading/caching of drawings. ## 0.2.0 @@ -157,14 +170,16 @@ ## 0.1.0 -Bumping minor version due to internal breaking changes and new support. Works on dev channel as of release (Flutter >= 0.3.6). +Bumping minor version due to internal breaking changes and new support. Works on +dev channel as of release (Flutter >= 0.3.6). - Refactor `DrawableRoot` to support top level style definition. - Support for dash paths. - Support for more inherited attributes. - Initial support for `@style` attributes. - Support for `rgb()` color attribute/styles. -- Change painting order from stroke first, then fill to fill first, then stroke (matches Chrome rendering of `assets/simple/style_attr.svg`). +- Change painting order from stroke first, then fill to fill first, then stroke + (matches Chrome rendering of `assets/simple/style_attr.svg`). ## 0.0.2 From d6fe97c1b93cce0e0ab1e98c872bbb7a4ad00afd Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 28 Nov 2018 10:02:25 -0800 Subject: [PATCH 180/512] Cleanup, start image --- third_party/lib/src/svg_parser.dart | 7 +- third_party/lib/src/utilities/xml.dart | 14 ++ third_party/lib/src/vector_drawable.dart | 22 ++- third_party/lib/svg.dart | 168 ++++++++++++----------- third_party/test/xml_svg_test.dart | 19 ++- 5 files changed, 137 insertions(+), 93 deletions(-) diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 36d9032904c8..8a421ebde8ba 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -138,12 +138,7 @@ Drawable parseSvgElement( } else if (el.name.local == 'svg') { throw UnsupportedError('Nested SVGs not supported in this implementation.'); } else if (el.name.local == 'use') { - final String xlinkHref = getAttribute( - el, - 'href', - namespace: 'http://www.w3.org/1999/xlink', - def: getAttribute(el, 'href'), - ); + final String xlinkHref = getHrefAttribute(el); final DrawableStyle style = parseStyle( el, definitions, diff --git a/third_party/lib/src/utilities/xml.dart b/third_party/lib/src/utilities/xml.dart index eb3fd2f89b74..1b67d30d0579 100644 --- a/third_party/lib/src/utilities/xml.dart +++ b/third_party/lib/src/utilities/xml.dart @@ -1,5 +1,19 @@ import 'package:xml/xml.dart'; +/// The namespace for xlink from the SVG 1.1 spec. +const String kXlinkNamespace = 'http://www.w3.org/1999/xlink'; + +/// Get the `xlink:href` or `href` attribute, preferring `xlink`. +/// +/// SVG 1.1 specifies that these attributes should be in the xlink namespace. +/// SVG 2 deprecates that namespace. +String getHrefAttribute(XmlElement el) => getAttribute( + el, + 'href', + namespace: kXlinkNamespace, + def: getAttribute(el, 'href'), + ); + /// Gets the attribute, trims it, and returns the attribute or default if the attribute /// is null or ''. /// diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 7cc00204ddcc..c6dc83ed9b9e 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -1,7 +1,6 @@ import 'dart:typed_data'; import 'dart:ui'; -import 'package:flutter/widgets.dart' hide TextStyle; import 'package:meta/meta.dart'; import 'package:path_drawing/path_drawing.dart'; @@ -637,7 +636,8 @@ class DrawableNoop implements Drawable { void draw(Canvas canvas, ColorFilter colorFilter) {} } -/// Represents a group of drawing elements that may share a common `transform`, `stroke`, or `fill`. +/// Represents a group of drawing elements that may share a common `transform`, +/// `stroke`, or `fill`. class DrawableGroup implements DrawableStyleable { const DrawableGroup(this.children, this.style); @@ -721,6 +721,24 @@ class DrawableGroup implements DrawableStyleable { } } +/// A raster image (e.g. PNG, JPEG, or GIF) embedded in the drawable. +class DrawableRasterImage implements Drawable { + const DrawableRasterImage(this.image, this.offset) + : assert(image != null), + assert(offset != null); + + final Image image; + final Offset offset; + + @override + void draw(Canvas canvas, ColorFilter colorFilter) { + canvas.drawImage(image, offset, Paint()); + } + + @override + bool get hasDrawableContent => image.height > 0 && image.width > 0; +} + /// Represents a drawing element that will be rendered to the canvas. class DrawableShape implements Drawable, DrawableStyleable { const DrawableShape(this.path, this.style) diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 6243aa779034..a49b6a08d086 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -111,15 +111,13 @@ class Svg { final List children = svg.children .whereType() - .map( - (XmlNode child) => parseSvgElement( - child, - definitions, - viewBox.viewBoxRect, - style, - key, - ), - ) + .map((XmlNode child) => parseSvgElement( + child, + definitions, + viewBox.viewBoxRect, + style, + key, + )) .toList(); return DrawableRoot( viewBox, @@ -153,16 +151,17 @@ class SvgPicture extends StatefulWidget { /// /// A custom `placeholderBuilder` can be specified for cases where decoding or /// acquiring data may take a noticeably long time, e.g. for a network picture. - const SvgPicture(this.pictureProvider, - {Key key, - this.width, - this.height, - this.fit = BoxFit.contain, - this.alignment = Alignment.center, - this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder}) - : super(key: key); + const SvgPicture( + this.pictureProvider, { + Key key, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + }) : super(key: key); /// Instantiates a widget that renders an SVG picture from an [AssetBundle]. /// @@ -239,20 +238,21 @@ class SvgPicture extends StatefulWidget { /// scale is present. /// * , an introduction to assets in /// Flutter. - SvgPicture.asset(String assetName, - {Key key, - this.matchTextDirection = false, - AssetBundle bundle, - String package, - this.width, - this.height, - this.fit = BoxFit.contain, - this.alignment = Alignment.center, - this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder, - Color color, - BlendMode colorBlendMode = BlendMode.srcIn}) - : pictureProvider = ExactAssetPicture( + SvgPicture.asset( + String assetName, { + Key key, + this.matchTextDirection = false, + AssetBundle bundle, + String package, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn, + }) : pictureProvider = ExactAssetPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox : svgByteDecoder, @@ -289,19 +289,20 @@ class SvgPicture extends StatefulWidget { /// /// An optional `headers` argument can be used to send custom HTTP headers /// with the image request. - SvgPicture.network(String url, - {Key key, - Map headers, - this.width, - this.height, - this.fit = BoxFit.contain, - this.alignment = Alignment.center, - this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder, - Color color, - BlendMode colorBlendMode = BlendMode.srcIn}) - : pictureProvider = NetworkPicture( + SvgPicture.network( + String url, { + Key key, + Map headers, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn, + }) : pictureProvider = NetworkPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox : svgByteDecoder, @@ -335,18 +336,19 @@ class SvgPicture extends StatefulWidget { /// /// On Android, this may require the /// `android.permission.READ_EXTERNAL_STORAGE` permission. - SvgPicture.file(File file, - {Key key, - this.width, - this.height, - this.fit = BoxFit.contain, - this.alignment = Alignment.center, - this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder, - Color color, - BlendMode colorBlendMode = BlendMode.srcIn}) - : pictureProvider = FilePicture( + SvgPicture.file( + File file, { + Key key, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn, + }) : pictureProvider = FilePicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox : svgByteDecoder, @@ -376,18 +378,19 @@ class SvgPicture extends StatefulWidget { /// /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. - SvgPicture.memory(Uint8List bytes, - {Key key, - this.width, - this.height, - this.fit = BoxFit.contain, - this.alignment = Alignment.center, - this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder, - Color color, - BlendMode colorBlendMode = BlendMode.srcIn}) - : pictureProvider = MemoryPicture( + SvgPicture.memory( + Uint8List bytes, { + Key key, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn, + }) : pictureProvider = MemoryPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBox : svgByteDecoder, @@ -417,18 +420,19 @@ class SvgPicture extends StatefulWidget { /// /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. - SvgPicture.string(String bytes, - {Key key, - this.width, - this.height, - this.fit = BoxFit.contain, - this.alignment = Alignment.center, - this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder, - Color color, - BlendMode colorBlendMode = BlendMode.srcIn}) - : pictureProvider = StringPicture( + SvgPicture.string( + String bytes, { + Key key, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + Color color, + BlendMode colorBlendMode = BlendMode.srcIn, + }) : pictureProvider = StringPicture( allowDrawingOutsideViewBox == true ? svgStringDecoderOutsideViewBox : svgStringDecoder, diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index aee127df3a80..1fbbb4320b2a 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -7,11 +7,23 @@ import 'package:flutter_svg/src/svg/xml_parsers.dart'; import 'package:flutter_svg/src/utilities/xml.dart'; void main() { - test('Attribute and style tests', () { - final XmlElement el = parse( - '') + test('Xlink href tests', () { + final XmlElement el = parse('').rootElement; + + final XmlElement elXlink = parse('') .rootElement; + expect(getHrefAttribute(el), 'http://localhost'); + expect(getHrefAttribute(elXlink), 'http://localhost'); + }); + + test('Attribute and style tests', () { + final XmlElement el = + parse('') + .rootElement; + expect(getAttribute(el, 'stroke'), '#fff'); expect(getAttribute(el, 'fill'), '#eee'); expect(getAttribute(el, 'stroke-dashpattern'), '1 2'); @@ -22,6 +34,7 @@ void main() { expect(getAttribute(el, 'fill-opacity', checkStyle: false), ''); expect(getAttribute(el, 'fill', checkStyle: false), '#eee'); }); + // if the parsing logic changes, we can simplify some methods. for now assert that whitespace in attributes is preserved test('Attribute WhiteSpace test', () { final XmlDocument xd = From a6ccc999cdd871d05c975c02ddd1a0c041b17b4f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 28 Nov 2018 13:03:18 -0800 Subject: [PATCH 181/512] Cache by default --- third_party/CHANGELOG.md | 10 +++++++++- third_party/example/pubspec.lock | 2 +- third_party/lib/avd.dart | 4 ++-- third_party/lib/src/picture_provider.dart | 9 ++++----- third_party/lib/svg.dart | 4 ++-- third_party/pubspec.yaml | 2 +- 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index e256696bb0d4..2a43671d1275 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,8 +1,16 @@ # CHANGES +## 0.7.0+1 + +- By default, `SvgPicture.asset` will now cache the asset. We already cached the + final picture, but the caching included any color filtering provided on the + image. This is problematic if the color is animated. See + https://github.com/dnfield/flutter_svg/issues/33 + ## 0.7.0 -- **BREAKING** Correct erroneous `width` and `height` processing on the root element. +- **BREAKING** Correct erroneous `width` and `height` processing on the root + element. - Previously, `width` and `height` were treated as synonyms for the width and height of the `viewBox`. This is not correct, and resulted in meaningful rendering errors in some scenarios compared to Chrome. Fixing this makes the diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index f5d2001ff557..15572bb3d89b 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.7.0" + version: "0.7.0+1" meta: dependency: transitive description: diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index dd6747d124fb..5d8298efff37 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -119,8 +119,8 @@ class AvdPicture extends SvgPicture { : this( ExactAssetPicture( allowDrawingOutsideViewBox == true - ? avdByteDecoderOutsideViewBox - : avdByteDecoder, + ? avdStringDecoderOutsideViewBox + : avdStringDecoder, assetName, bundle: bundle, package: package, diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 382706e0d076..796983a8922f 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -397,7 +397,7 @@ abstract class AssetBundlePictureProvider /// const constructors so that they can be used in const expressions. const AssetBundlePictureProvider(this.decoder) : assert(decoder != null); - final PictureInfoDecoder decoder; + final PictureInfoDecoder decoder; /// Converts a key into an [PictureStreamCompleter], and begins fetching the /// picture using [_loadAsync]. @@ -416,13 +416,12 @@ abstract class AssetBundlePictureProvider /// This function is used by [load]. @protected Future _loadAsync(AssetBundlePictureKey key) async { - final ByteData data = await key.bundle.load(key.name); + final String data = await key.bundle.loadString(key.name); if (data == null) { throw 'Unable to read data'; } - return await decoder( - data.buffer.asUint8List(), key.colorFilter, key.toString()); + return await decoder(data, key.colorFilter, key.toString()); } } @@ -760,7 +759,7 @@ class ExactAssetPicture extends AssetBundlePictureProvider { /// included in a package. See the documentation for the [ExactAssetPicture] class /// itself for details. const ExactAssetPicture( - PictureInfoDecoder decoder, + PictureInfoDecoder decoder, this.assetName, { this.bundle, this.package, diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index a49b6a08d086..5e8bc532ab36 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -254,8 +254,8 @@ class SvgPicture extends StatefulWidget { BlendMode colorBlendMode = BlendMode.srcIn, }) : pictureProvider = ExactAssetPicture( allowDrawingOutsideViewBox == true - ? svgByteDecoderOutsideViewBox - : svgByteDecoder, + ? svgStringDecoderOutsideViewBox + : svgStringDecoder, assetName, bundle: bundle, package: package, diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 6d2754f2b56c..e0373d4a78f8 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.7.0 +version: 0.7.0+1 dependencies: path_drawing: ^0.4.0 From 4bece57c4ef1fd5ab2b7ebad5bcdb600143e65b4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 28 Nov 2018 14:15:53 -0800 Subject: [PATCH 182/512] fix test --- third_party/test/widget_svg_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 1d1c67e801e1..8b8a98a88886 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -134,8 +134,8 @@ void main() { testWidgets('SvgPicture.asset', (WidgetTester tester) async { final MockAssetBundle mockAsset = MockAssetBundle(); - when(mockAsset.load('test.svg')) - .thenAnswer((_) => Future.value(ByteData.view(svg.buffer))); + when(mockAsset.loadString('test.svg')) + .thenAnswer((_) => Future.value(svgStr)); final GlobalKey key = GlobalKey(); await tester.pumpWidget( From 8498d2b4ee3191dcc7f8a335f88f1d2484f9a4ba Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 28 Nov 2018 19:34:51 -0800 Subject: [PATCH 183/512] support for --- third_party/CHANGELOG.md | 6 ++ third_party/example/assets/simple/image.svg | 6 ++ third_party/example/lib/main.dart | 5 ++ third_party/example/pubspec.lock | 2 +- third_party/golden/simple/image.png | Bin 0 -> 684 bytes third_party/lib/src/picture_provider.dart | 17 +---- third_party/lib/src/svg/xml_parsers.dart | 4 +- third_party/lib/src/svg_parser.dart | 79 +++++++++++++++----- third_party/lib/src/utilities/http.dart | 21 ++++++ third_party/lib/src/vector_drawable.dart | 34 ++++++++- third_party/lib/svg.dart | 32 ++++---- third_party/pubspec.yaml | 2 +- third_party/test/golden_svg_test.dart | 3 + third_party/tool/gen_golden.dart | 8 +- 14 files changed, 166 insertions(+), 53 deletions(-) create mode 100644 third_party/example/assets/simple/image.svg create mode 100644 third_party/golden/simple/image.png create mode 100644 third_party/lib/src/utilities/http.dart diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 2a43671d1275..f58bdef47e73 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGES +## 0.8.0 + +- Made parsing `async` to support image loading. +- Added support for `` elements. + + ## 0.7.0+1 - By default, `SvgPicture.asset` will now cache the asset. We already cached the diff --git a/third_party/example/assets/simple/image.svg b/third_party/example/assets/simple/image.svg new file mode 100644 index 000000000000..07d0057fdbb3 --- /dev/null +++ b/third_party/example/assets/simple/image.svg @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index f5c1de48b760..3a76400e2ae9 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -118,6 +118,11 @@ class _MyHomePageState extends State { ), ); } + // Shows an example of an SVG image that will fetch a raster image from a URL. + _painters.add(SvgPicture.string(''' + +''')); _painters.add(AvdPicture.asset('assets/android_vd/battery_charging.xml')); } diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index 15572bb3d89b..fe32aced9a86 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.7.0+1" + version: "0.8.0" meta: dependency: transitive description: diff --git a/third_party/golden/simple/image.png b/third_party/golden/simple/image.png new file mode 100644 index 0000000000000000000000000000000000000000..20796dcb6bc7dfc1df334212d609cc213ee46375 GIT binary patch literal 684 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q`uPZ!6KiaBrZ8uA@h5MXc=e)>ONEq7IJ2aBWeUO|!7s}Cffvz#xQtW&%1 z?xT-8Z)bmJdyvA^s35?BpGdar=N8nyqrP(%CzGRs01KUohkwuP+;&J}|IL$ntDis5 zQsZE0bPymww0!@>^)9%;P?)93L4kt=!q4Q`|Np-~3NcxpEtgQb=?C;~(X99BQ*2gl sx%+E(#GiQveThv3ttY~TLq*9ChLZE*-Akudr!WA4r>mdKI;Vst05vn4xc~qF literal 0 HcmV?d00001 diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 796983a8922f..835098400877 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -15,6 +15,7 @@ import 'package:flutter/widgets.dart' import 'picture_cache.dart'; import 'picture_stream.dart'; +import 'utilities/http.dart'; typedef PictureInfoDecoder = FutureOr Function( T data, ColorFilter colorFilter, String key); @@ -425,8 +426,6 @@ abstract class AssetBundlePictureProvider } } -final HttpClient _httpClient = HttpClient(); - /// Fetches the given URL from the network, associating it with the given scale. /// /// The picture will be cached regardless of cache headers from the server. @@ -471,19 +470,7 @@ class NetworkPicture extends PictureProvider { Future _loadAsync(NetworkPicture key) async { assert(key == this); - final Uri uri = Uri.base.resolve(url); - final HttpClientRequest request = await _httpClient.getUrl(uri); - if (headers != null) { - headers.forEach((String key, String value) { - request.headers.add(key, value); - }); - } - final HttpClientResponse response = await request.close(); - - if (response.statusCode != HttpStatus.ok) { - throw HttpException('Could not get network asset', uri: uri); - } - final Uint8List bytes = await consolidateHttpClientResponseBytes(response); + final Uint8List bytes = await httpGet(url); return await decoder(bytes, colorFilter, key.toString()); } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 5ce17b5311f2..b3f516264147 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -109,7 +109,9 @@ Iterable parseDefs(XmlElement el, if (def is XmlElement) { if (def.name.local.endsWith('Gradient')) { definitions.addPaintServer( - buildUrlIri(def), parseGradient(def, rootBounds)); + buildUrlIri(def), + parseGradient(def, rootBounds), + ); } else if (def.name.local == 'clipPath') { definitions.addClipPath(buildUrlIri(def), parseClipPathDefinition(def)); } else { diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 8a421ebde8ba..cfe006c3ff1c 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -1,3 +1,6 @@ +import 'dart:async'; +import 'dart:convert' hide Codec; +import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter/foundation.dart'; @@ -6,6 +9,7 @@ import 'package:vector_math/vector_math_64.dart'; import 'svg/parsers.dart'; import 'svg/xml_parsers.dart'; +import 'utilities/http.dart'; import 'utilities/xml.dart'; import 'vector_drawable.dart'; @@ -55,21 +59,21 @@ class DrawableSvgShape extends DrawableShape { /// Creates a [Drawable] from an SVG or shape element. Also handles parsing and gradients. /// /// If an unsupported element is encountered, it will be created as a [DrawableNoop]. -Drawable parseSvgElement( +Future parseSvgElement( XmlElement el, DrawableDefinitionServer definitions, Rect rootBounds, DrawableStyle parentStyle, String key, { bool isDef = false, -}) { +}) async { assert(isDef != null); final Function unhandled = (XmlElement e) => _unhandledElement(e, key); - final Function createDefinition = (String iri, XmlElement defEl) { + final Function createDefinition = (String iri, XmlElement defEl) async { assert(iri != emptyUrlIri); definitions.addDrawable( iri, - parseSvgElement( + await parseSvgElement( defEl, definitions, rootBounds, @@ -102,11 +106,11 @@ Drawable parseSvgElement( in unhandledDef.children.whereType()) { iri = buildUrlIri(child); if (iri != emptyUrlIri) { - createDefinition(iri, child); + await createDefinition(iri, child); } } } else { - createDefinition(iri, unhandledDef); + await createDefinition(iri, unhandledDef); } } return DrawableNoop(el.name.local); @@ -119,7 +123,7 @@ Drawable parseSvgElement( } else if (el.name.local == 'g' || el.name.local == 'a' || el.name.local == 'symbol') { - final DrawableGroup group = parseSvgGroup( + final DrawableGroup group = await parseSvgGroup( el, definitions, rootBounds, @@ -137,6 +141,18 @@ Drawable parseSvgElement( return parseSvgText(el, definitions, rootBounds, parentStyle); } else if (el.name.local == 'svg') { throw UnsupportedError('Nested SVGs not supported in this implementation.'); + } else if (el.name.local == 'image') { + final String href = getHrefAttribute(el); + final Offset offset = Offset( + double.parse(getAttribute(el, 'x', def: '0')), + double.parse(getAttribute(el, 'y', def: '0')), + ); + final Size size = Size( + double.parse(getAttribute(el, 'width', def: '0')), + double.parse(getAttribute(el, 'height', def: '0')), + ); + final Image image = await _resolveImage(href); + return DrawableRasterImage(image, offset, size: size); } else if (el.name.local == 'use') { final String xlinkHref = getHrefAttribute(el); final DrawableStyle style = parseStyle( @@ -276,19 +292,23 @@ Drawable parseSvgText(XmlElement el, DrawableDefinitionServer definitions, } /// Parses an SVG element. -Drawable parseSvgGroup(XmlElement el, DrawableDefinitionServer definitions, - Rect bounds, DrawableStyle parentStyle, String key) { +Future parseSvgGroup( + XmlElement el, + DrawableDefinitionServer definitions, + Rect bounds, + DrawableStyle parentStyle, + String key) async { final List children = []; final DrawableStyle style = parseStyle(el, definitions, bounds, parentStyle, needsTransform: true); - for (XmlNode child in el.children) { - if (child is XmlElement) { - final Drawable el = - parseSvgElement(child, definitions, bounds, style, key); - if (el != null) { - children.add(el); - } - } + for (XmlNode child in el.children.whereType()) { + children.add(await parseSvgElement( + child, + definitions, + bounds, + style, + key, + )); } return DrawableGroup(children, style); @@ -329,3 +349,28 @@ DrawableStyle parseStyle( ), ); } + +Future _resolveImage(String href) async { + if (href == null || href == '') { + return null; + } + + final Function decodeImage = (Uint8List bytes) async { + final Codec codec = await instantiateImageCodec(bytes); + final FrameInfo frame = await codec.getNextFrame(); + return frame.image; + }; + + if (href.startsWith('http')) { + final Uint8List bytes = await httpGet(href); + return decodeImage(bytes); + } + + if (href.startsWith('data:')) { + final int commaLocation = href.indexOf(',') + 1; + final Uint8List bytes = base64.decode(href.substring(commaLocation)); + return decodeImage(bytes); + } + + throw UnsupportedError('Could not resolve image href: $href'); +} diff --git a/third_party/lib/src/utilities/http.dart b/third_party/lib/src/utilities/http.dart new file mode 100644 index 000000000000..5a8e24262fd2 --- /dev/null +++ b/third_party/lib/src/utilities/http.dart @@ -0,0 +1,21 @@ +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:flutter/foundation.dart'; + +Future httpGet(String url, {Map headers}) async { + final HttpClient httpClient = HttpClient(); + final Uri uri = Uri.base.resolve(url); + final HttpClientRequest request = await httpClient.getUrl(uri); + if (headers != null) { + headers.forEach((String key, String value) { + request.headers.add(key, value); + }); + } + final HttpClientResponse response = await request.close(); + + if (response.statusCode != HttpStatus.ok) { + throw HttpException('Could not get network asset', uri: uri); + } + return consolidateHttpClientResponseBytes(response); +} diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index c6dc83ed9b9e..f3ded2d45539 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -1,3 +1,4 @@ +import 'dart:math' as math; import 'dart:typed_data'; import 'dart:ui'; @@ -408,7 +409,10 @@ class DrawableText implements Drawable { } static Offset resolveOffset( - Paragraph paragraph, DrawableTextAnchorPosition anchor, Offset offset) { + Paragraph paragraph, + DrawableTextAnchorPosition anchor, + Offset offset, + ) { assert(paragraph != null); assert(anchor != null); assert(offset != null); @@ -723,16 +727,40 @@ class DrawableGroup implements DrawableStyleable { /// A raster image (e.g. PNG, JPEG, or GIF) embedded in the drawable. class DrawableRasterImage implements Drawable { - const DrawableRasterImage(this.image, this.offset) + const DrawableRasterImage(this.image, this.offset, {this.size}) : assert(image != null), assert(offset != null); final Image image; final Offset offset; + final Size size; @override void draw(Canvas canvas, ColorFilter colorFilter) { - canvas.drawImage(image, offset, Paint()); + final Size imageSize = Size( + image.width.toDouble(), + image.height.toDouble(), + ); + Size desiredSize = imageSize; + double scale = 1.0; + if (size != null) { + desiredSize = size; + scale = math.min( + size.width / image.width, + size.height / image.height, + ); + } + if (scale != 1.0 || offset != Offset.zero) { + final Offset shift = desiredSize / 2.0 - imageSize * scale / 2.0; + canvas.save(); + canvas.translate(offset.dx + shift.dx, offset.dy + shift.dy); + canvas.scale(scale, scale); + } + + canvas.drawImage(image, Offset.zero, Paint()); + if (scale != 1.0 || offset != Offset.zero) { + canvas.restore(); + } } @override diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 5e8bc532ab36..3ca1c2c55e88 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -65,9 +65,12 @@ class Svg { /// The `colorFilter` property will be applied to any [Paint] objects used during drawing. /// /// The [key] will be used for debugging purposes. - FutureOr svgPictureStringDecoder(String raw, - bool allowDrawingOutsideOfViewBox, ColorFilter colorFilter, String key) { - final DrawableRoot svg = fromSvgString(raw, key); + FutureOr svgPictureStringDecoder( + String raw, + bool allowDrawingOutsideOfViewBox, + ColorFilter colorFilter, + String key) async { + final DrawableRoot svg = await fromSvgString(raw, key); return PictureInfo( picture: svg.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, @@ -102,23 +105,24 @@ class Svg { /// Creates a [DrawableRoot] from a string of SVG data. /// /// The `key` is used for debugging purposes. - DrawableRoot fromSvgString(String rawSvg, String key) { + Future fromSvgString(String rawSvg, String key) async { final XmlElement svg = xml.parse(rawSvg).rootElement; final DrawableViewport viewBox = parseViewBox(svg); final DrawableDefinitionServer definitions = DrawableDefinitionServer(); final DrawableStyle style = parseStyle(svg, definitions, viewBox.viewBoxRect, null); - final List children = svg.children - .whereType() - .map((XmlNode child) => parseSvgElement( - child, - definitions, - viewBox.viewBoxRect, - style, - key, - )) - .toList(); + final List children = []; + for (XmlElement child in svg.children.whereType()) { + children.add(await parseSvgElement( + child, + definitions, + viewBox.viewBoxRect, + style, + key, + )); + } + return DrawableRoot( viewBox, children, diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index e0373d4a78f8..44c358806108 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.7.0+1 +version: 0.8.0 dependencies: path_drawing: ^0.4.0 diff --git a/third_party/test/golden_svg_test.dart b/third_party/test/golden_svg_test.dart index 74b7d7471427..06bedc46de29 100644 --- a/third_party/test/golden_svg_test.dart +++ b/third_party/test/golden_svg_test.dart @@ -13,6 +13,9 @@ Iterable getGoldenFileNames() sync* { Directory(join(root, root.endsWith('test') ? '..' : '', 'golden')); for (FileSystemEntity fe in dir.listSync(recursive: true)) { if (fe is File && fe.path.toLowerCase().endsWith('.png')) { + if (fe.path.toLowerCase().contains('text') && !Platform.isLinux) { + continue; + } yield fe; } } diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index 8b2c4912a9c2..4c8442acd5a0 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -21,7 +21,8 @@ Future getSvgPngBytes(String svgData) async { const Size size = Size(200.0, 200.0); - final DrawableRoot svgRoot = svg.fromSvgString(svgData, 'GenGoldenTest'); + final DrawableRoot svgRoot = + await svg.fromSvgString(svgData, 'GenGoldenTest'); svgRoot.scaleCanvasToViewBox(canvas, size); svgRoot.clipCanvasToViewBox(canvas); @@ -40,6 +41,11 @@ Iterable getSvgFileNames() sync* { final Directory dir = Directory('./example/assets'); for (FileSystemEntity fe in dir.listSync(recursive: true)) { if (fe is File && fe.path.toLowerCase().endsWith('.svg')) { + // Skip text based tests unless we're on Linux - these have + // subtle platform specific differences. + if (fe.path.toLowerCase().contains('text') && !Platform.isLinux) { + continue; + } yield fe; } } From 7b0dc98c3020b79f4eac1b9fa6f77b789ad40ada Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Dec 2018 21:56:21 -0800 Subject: [PATCH 184/512] revert faulty scaling logic --- third_party/example/lib/main.dart | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index 3a76400e2ae9..1988c96078d4 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -89,6 +89,21 @@ class _MyHomePageState extends State { super.initState(); _dimension = 250.0; + _painters.add(SvgPicture.string(''' + + Close + Created with Sketch. + + + + + + + + + + +''')); for (String assetName in assetNames) { _painters.add( SvgPicture.asset(assetName), From 4673e2f77cb3c1ec1cd4acfb5c7af1504b911804 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Dec 2018 21:56:55 -0800 Subject: [PATCH 185/512] revert faulty scaling logic --- .../golden/simple/width_height_viewbox.png | Bin 540 -> 2213 bytes third_party/lib/src/picture_provider.dart | 9 +++++++-- third_party/lib/src/render_picture.dart | 9 +++------ third_party/lib/svg.dart | 15 +++++++++------ 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/third_party/golden/simple/width_height_viewbox.png b/third_party/golden/simple/width_height_viewbox.png index a5227551975c5b74545e9f6cefb6535767fc90cf..7a06e89fab9021fcf3095df6f9aa999607ad788c 100644 GIT binary patch literal 2213 zcmbVOdsq`!7N1FwgjYy{Mgy}l2?ItYDi38q=!O_b!n3g2g(^`HMAT}6RDz%;7#>+& zNKyog0$ssJYXNyE_<=Qzfe;iC>}p%ok_2B>>{8gJ2tu#@d;i#P=lf>PJ?Gr>yL0C| zzuz78hjBs|M|VdEf?UKRK_aky?{Bg_cs3?A)dB+_Oce5=rn|^X;Mg7Hi#Lo&g_HviSI+ie3#T9RE%COHTj2Z3^E!&sc)|LOR z;1}pnV_f432778?LLPdqBIJi-^`sB`vkB)md&3D|=@gtTVqV2p7#g*OPCdWMp)~Q7 zo#4x;|2@4D(Y!l47#Le`5M zaIb&AT-yl^r~RX7?A6D9hPQl<7ZAuTnWd*|LpC#OBB#eex6PRsJ+4h)Ax zpUBFp)H$GxrNh>k=u8=_aUc*WeHzgoI&w96t8qHH`V$V-)#*iQZ**I`qAnw&HlCG2az$qfkoP9I ze_Fhs7rN#_W?o3N9de$Q`I2C~&#yUC5)ffX`1#0%XS`6~;YYr8Ty|OFVB7jdX?e=Z zek;?<#`$;1&H(U!7q?X2t%ikPnv%~zE$!=Wv`U}F;8Bf(kL>#PT(!>6f74SR8$=gJ zBIjpk^FO-0<+IEnI6F7jw7+BL4M~T*`(-3*J_&|xBjcT2U3-6>+tnPdYH+1nc9#&{ z7Z}l^AKA3BYxozpW>NmIy;|CCf@_|Lm+CUKWT7W=Z{k3UDxHZLhFnQG^Lr(%>lC$g zss|>1;L64(HDuv2WZet5B7QcLZdrDmXn)ivMRa!)8?j0CqX*X0bRi&og6LeZwo-F8 z5`<+67)3EpExE)6fr3o73H)&BaA54dj;%-M=YkJcy!m8<$2Z3oC@2ysRrsMA53|kY z1>HRQ&OKDT;A@4B^UxsO$>bh5QgXb&cXF?8Uve)TsZ?mv`$8z|ob6Ot_HwC02G*cW z77`H%W~nPyAft9h&#)(2A0YJ2D#tK{ynBs&`$N-`t zgDK@n0R*?dkVpp*$*nOs>HubX_ZJiCFwDAs;UtbSK_EDz2X+9Z+Y)ynn#E+YIXJ@v zt3lv9dfCH7BFqXtCG9@793*B{wqIh7cFkV8kYyd|IIyzW6Ozm2qcbzf_>=Q>=+E&% zK|%GxbybSF?brX~`zqd5exozI1c7zSc;Nt3PrqGFUuP|sFqHOP%L`Oen}AEmER`Nbw@?jL|R#f ztO9UMcY&v>cPZ0p+J(c;rPB5ukiRCX24Cg_Jc>U|5xb!!x0F>?RgCftkIBgSJ0gih zf+LjJ+Q)W%yV_DaMr8T_T|FpnZO{cr!QCiJZFI=-w z9YmnVgPi81{yn3uOtld49u!4d6ybH8sZwJ=nNEm#$@KcchI~F97Mk63L->w=byUlF zbO)iCNO!{Z`suXfNIFeu_NTAL^$_)n8uKsHMPQXu1r6QdB(_JqqeWj^piMlzy$&cB zLz85LdlmX5j47*#WVif{=uA-hiTrJxzw^?Vq-Bc;N3>+q)-Y|72`*OhJTb$>fiR6+ z5BDm0TY;0u)yltxDGHtka6aW~GwbY;%JJVJUX<4B-HR z8jh3>pxiM}7srr_Id5-0ENn86V0&=mwa6J^iG!Ra3~GgaDZ4i~{90adWzn}Pu4#7X zW$hK_iTAxXRa0aEnnVRq!MS^@^@sUaqFyWSOW%IGGLO45dN=cjQ!FW}hYecRy>>eH z^HqA$xrMKH8Sor#vTdGv#eeCPTibGTXDu`H4G#AD8szoz&b@89x=ZKWzP69QqHE)U zHix)z4*} HQ$iB}pR2eO diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 835098400877..47464fd60ab7 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -781,8 +781,13 @@ class ExactAssetPicture extends AssetBundlePictureProvider { @override Future obtainKey() { - return SynchronousFuture(AssetBundlePictureKey( - bundle: bundle ?? rootBundle, name: keyName, colorFilter: colorFilter)); + return SynchronousFuture( + AssetBundlePictureKey( + bundle: bundle ?? rootBundle, + name: keyName, + colorFilter: colorFilter, + ), + ); } @override diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index c9686e2a257d..bd9c395cd746 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -188,14 +188,14 @@ class RenderPicture extends RenderBox { } return true; }()); - final Rect viewportRect = - Offset.zero & (_picture.viewport.size * _devicePixelRatio); scaleCanvasToViewBox( context.canvas, size, _picture.viewport, _picture.size, ); + final Rect viewportRect = + Offset.zero & (_picture.viewport.size * _devicePixelRatio); if (allowDrawingOutsideViewBox != true) { context.canvas.clipRect(viewportRect); } @@ -210,10 +210,7 @@ void scaleCanvasToViewBox( Rect viewBox, Size pictureSize, ) { - if (pictureSize.isFinite) { - final Offset shift = desiredSize / 2.0 - pictureSize / 2.0; - canvas.translate(shift.dx, shift.dy); - } else if (desiredSize != viewBox.size) { + if (desiredSize != viewBox.size) { final double scale = math.min( desiredSize.width / viewBox.width, desiredSize.height / viewBox.height, diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 3ca1c2c55e88..fe7cfce6a7dd 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -40,14 +40,16 @@ class Svg { /// /// The [key] will be used for debugging purposes. FutureOr svgPictureDecoder( - Uint8List raw, - bool allowDrawingOutsideOfViewBox, - ColorFilter colorFilter, - String key) async { + Uint8List raw, + bool allowDrawingOutsideOfViewBox, + ColorFilter colorFilter, + String key, + ) async { final DrawableRoot svgRoot = await fromSvgBytes(raw, key); final Picture pic = svgRoot.toPicture( - clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, - colorFilter: colorFilter); + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, + colorFilter: colorFilter, + ); return PictureInfo( picture: pic, viewport: svgRoot.viewport.viewBoxRect, @@ -75,6 +77,7 @@ class Svg { picture: svg.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter, + size: svg.viewport.viewBox, ), viewport: svg.viewport.viewBoxRect, size: svg.viewport.size, From 2ed2b91d742d1be9c74e296e6907479e326fa8a0 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 17 Dec 2018 10:32:08 -0800 Subject: [PATCH 186/512] revert width/height update doc --- third_party/CHANGELOG.md | 6 ++++++ third_party/example/pubspec.lock | 2 +- third_party/pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index f58bdef47e73..60a78809c303 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGES +## 0.8.1 + +- Revert changes made on 0.7.0 to attempt to utilize `width` and `height`. These + changes did not quite fix what they were intended to fix and caused problems + they weren't intended to case. + ## 0.8.0 - Made parsing `async` to support image loading. diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index fe32aced9a86..aa96fd031869 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.8.0" + version: "0.8.1" meta: dependency: transitive description: diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 44c358806108..6efae5b3e53b 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.8.0 +version: 0.8.1 dependencies: path_drawing: ^0.4.0 From 05d85884e7ab251b1bc443c8446249d2feb7e6ec Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 18 Dec 2018 09:36:40 -0800 Subject: [PATCH 187/512] fix crasher for DrawableNoop, improve error reporting --- third_party/lib/src/svg_parser.dart | 5 +++++ third_party/lib/src/vector_drawable.dart | 11 ++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index cfe006c3ff1c..71e00c47b5f0 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -100,6 +100,10 @@ Future parseSvgElement( rootBounds, ); for (XmlElement unhandledDef in unhandledDefs) { + if (unhandledDef.name.local == 'style') { + unhandled(unhandledDef); + continue; + } String iri = buildUrlIri(unhandledDef); if (iri == emptyUrlIri) { for (XmlElement child @@ -197,6 +201,7 @@ void _unhandledElement(XmlElement el, String key) { library: 'SVG', context: 'in parseSvgElement', )); + return; } assert(() { if (_unhandledElements.add(el.name.local)) { diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index f3ded2d45539..b4885e707cf0 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -628,7 +628,7 @@ class DrawableRoot implements Drawable { /// Represents an element that is not rendered and has no chidlren, e.g. /// a descriptive element. // TODO(dnfield): tie some of this into semantics/accessibility -class DrawableNoop implements Drawable { +class DrawableNoop implements DrawableStyleable { const DrawableNoop(this.name); final String name; @@ -638,6 +638,15 @@ class DrawableNoop implements Drawable { @override void draw(Canvas canvas, ColorFilter colorFilter) {} + + @override + DrawableStyleable mergeStyle(DrawableStyle newStyle) => this; + + @override + DrawableStyleable replaceStyle(DrawableStyle newStyle) => this; + + @override + DrawableStyle get style => null; } /// Represents a group of drawing elements that may share a common `transform`, From 19ad168b896cef649172cc63f6e16340b92f4e20 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 18 Dec 2018 09:38:52 -0800 Subject: [PATCH 188/512] bump version --- third_party/CHANGELOG.md | 6 ++++++ third_party/example/lib/main.dart | 36 +++++++++++++++++++++---------- third_party/example/pubspec.lock | 2 +- third_party/pubspec.yaml | 2 +- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 60a78809c303..6e99a4043b1f 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGES +## 0.8.2 + +- Make `DrawableNoop` implement `DrawableStyleable` to avoid crashing with + certain unhandled elements. +- Improve error reporting for certain ` \ No newline at end of file diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index 96b66c70787c..4c8442acd5a0 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -41,7 +41,8 @@ Iterable getSvgFileNames() sync* { final Directory dir = Directory('./example/assets'); for (FileSystemEntity fe in dir.listSync(recursive: true)) { if (fe is File && fe.path.toLowerCase().endsWith('.svg')) { - // Skip text based tests unless we can fix the rendering on Linux + // Skip text based tests unless we're on Linux - these have + // subtle platform specific differences. if (fe.path.toLowerCase().contains('text') && !Platform.isLinux) { continue; } From 1769cce96d3975e8864671a56d9649d413d0fc7f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 28 Dec 2018 18:55:42 -0800 Subject: [PATCH 195/512] Prefer usvg to svgcleaner now --- third_party/lib/src/svg_parser.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 71e00c47b5f0..3a8fa0b37b73 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -193,8 +193,8 @@ void _unhandledElement(XmlElement el, String key) { 'Style elements are not supported by this library and the requested SVG may not ' 'render as intended.\n' 'If possible, ensure the SVG uses inline styles and/or attributes (which are ' - 'supported), or use a preprocessing utility such as svgcleaner to inline the ' - 'styles for you.'); + 'supported), or use a preprocessing utility such as usvg (https://github.com/RazrFalcon/resvg/tree/master/usvg) ' + 'to inline the styles for you.'); buff.writeln(); buff.writeln('Picture key: $key'); }, From 921b729cc81648c1e06e03a4c1f537db865ef0f7 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 28 Dec 2018 19:23:47 -0800 Subject: [PATCH 196/512] Support non-def clipPath and `use` in clipPath --- .../assets/noto-emoji/emoji_u1f600.svg | 48 ++++++++++++++++++ .../golden/noto-emoji/emoji_u1f600.png | Bin 0 -> 9296 bytes third_party/lib/src/svg/xml_parsers.dart | 26 +++++++++- third_party/lib/src/svg_parser.dart | 8 +++ 4 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 third_party/example/assets/noto-emoji/emoji_u1f600.svg create mode 100644 third_party/golden/noto-emoji/emoji_u1f600.png diff --git a/third_party/example/assets/noto-emoji/emoji_u1f600.svg b/third_party/example/assets/noto-emoji/emoji_u1f600.svg new file mode 100644 index 000000000000..9916423433b1 --- /dev/null +++ b/third_party/example/assets/noto-emoji/emoji_u1f600.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/golden/noto-emoji/emoji_u1f600.png b/third_party/golden/noto-emoji/emoji_u1f600.png new file mode 100644 index 0000000000000000000000000000000000000000..182a392a4aa152c4c3fad9b1853504b9b697e64d GIT binary patch literal 9296 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 literal 0 HcmV?d00001 diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index b3f516264147..1df9b7728142 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -5,6 +5,7 @@ import 'package:path_drawing/path_drawing.dart'; import 'package:vector_math/vector_math_64.dart'; import 'package:xml/xml.dart'; +import '../svg_parser.dart'; import '../utilities/xml.dart'; import '../vector_drawable.dart'; import 'colors.dart'; @@ -113,7 +114,13 @@ Iterable parseDefs(XmlElement el, parseGradient(def, rootBounds), ); } else if (def.name.local == 'clipPath') { - definitions.addClipPath(buildUrlIri(def), parseClipPathDefinition(def)); + definitions.addClipPath( + buildUrlIri(def), + parseClipPathDefinition( + def, + definitions, + ), + ); } else { yield def; } @@ -324,7 +331,10 @@ PaintServer parseRadialGradient(XmlElement el, Rect rootBounds) { }; } -List parseClipPathDefinition(XmlElement el) { +List parseClipPathDefinition( + XmlElement el, + DrawableDefinitionServer definitions, +) { final List ret = []; Path currentPath; for (XmlNode child in el.children) { @@ -342,6 +352,18 @@ List parseClipPathDefinition(XmlElement el) { } else { currentPath.addPath(nextPath, Offset.zero); } + } else if (child.name.local == 'use') { + final String xlinkHref = getHrefAttribute(child); + final DrawableStyleable target = definitions.getDrawable('url($xlinkHref)'); + print(target); + if (target is DrawableShape) { + return [target.path]; + } else if (target is DrawableGroup) { + return target.children + .whereType() + .map((DrawableShape d) => d.path) + .toList(); + } } else { print('Unsupported clipPath child ${el.name.local}'); } diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 3a8fa0b37b73..8600e8adf52e 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -124,6 +124,14 @@ Future parseSvgElement( parseGradient(el, rootBounds), ); return DrawableNoop(el.name.local); + } else if (el.name.local == 'clipPath') { + definitions.addClipPath( + buildUrlIri(el), + parseClipPathDefinition( + el, + definitions, + ), + ); } else if (el.name.local == 'g' || el.name.local == 'a' || el.name.local == 'symbol') { From 9c7c0e2e9ef388909db644aea6531d19d2c9bbdf Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 28 Dec 2018 19:27:23 -0800 Subject: [PATCH 197/512] remove unused import --- third_party/lib/src/svg/xml_parsers.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 1df9b7728142..9b2187703f20 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -5,7 +5,6 @@ import 'package:path_drawing/path_drawing.dart'; import 'package:vector_math/vector_math_64.dart'; import 'package:xml/xml.dart'; -import '../svg_parser.dart'; import '../utilities/xml.dart'; import '../vector_drawable.dart'; import 'colors.dart'; From 78f65a2aeff4bd91924fe513d00248cb76c0c2cf Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 28 Dec 2018 19:45:04 -0800 Subject: [PATCH 198/512] fix group processing for clipPath use --- third_party/lib/src/svg/xml_parsers.dart | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 9b2187703f20..3aa09d87abbb 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -353,16 +353,20 @@ List parseClipPathDefinition( } } else if (child.name.local == 'use') { final String xlinkHref = getHrefAttribute(child); - final DrawableStyleable target = definitions.getDrawable('url($xlinkHref)'); - print(target); - if (target is DrawableShape) { - return [target.path]; - } else if (target is DrawableGroup) { - return target.children - .whereType() - .map((DrawableShape d) => d.path) - .toList(); + final DrawableStyleable definitionDrawable = + definitions.getDrawable('url($xlinkHref)'); + final List paths = []; + + void extractPathsFromDrawable(Drawable target) { + if (target is DrawableShape) { + paths.add(target.path); + } else if (target is DrawableGroup) { + target.children.forEach(extractPathsFromDrawable); + } } + + extractPathsFromDrawable(definitionDrawable); + return paths; } else { print('Unsupported clipPath child ${el.name.local}'); } From 77dc909d140f7ba0fb16215028f30321bcf1ed33 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 28 Dec 2018 19:52:11 -0800 Subject: [PATCH 199/512] v0.8.3 --- third_party/CHANGELOG.md | 6 ++++++ third_party/example/pubspec.lock | 2 +- third_party/pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 6e99a4043b1f..cd954644a615 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGES +## 0.8.3 + +- Implement support for `clipPath` outside of `defs` eleemnts. +- Implement support for `use` in a `clipPath`. +- Recommend `usvg` rather than `svgcleaner` per author's recommendation. + ## 0.8.2 - Make `DrawableNoop` implement `DrawableStyleable` to avoid crashing with diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index a4a70e24893b..3a688b3a0a96 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.8.2" + version: "0.8.3" meta: dependency: transitive description: diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 125cdff2dd67..51eef9d8923f 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.8.2 +version: 0.8.3 dependencies: path_drawing: ^0.4.0 From de98dbf351ec9de1e4cbd30ce892b5dff59679b9 Mon Sep 17 00:00:00 2001 From: Kris Pypen Date: Mon, 31 Dec 2018 01:03:14 +0100 Subject: [PATCH 200/512] Text support improvements (#92) * Text support improvements: * font-weight is now parsed to flutter font-weight values * font-family is now inherited * dx-dy-x-y fixed, also with tspan support * fill without stroke was broken --- third_party/example/assets/simple/text_2.svg | 28 ++++++ third_party/example/lib/main.dart | 1 + third_party/lib/src/svg_parser.dart | 93 +++++++++++++++----- third_party/lib/src/vector_drawable.dart | 6 +- 4 files changed, 103 insertions(+), 25 deletions(-) create mode 100644 third_party/example/assets/simple/text_2.svg diff --git a/third_party/example/assets/simple/text_2.svg b/third_party/example/assets/simple/text_2.svg new file mode 100644 index 000000000000..077e16e4678b --- /dev/null +++ b/third_party/example/assets/simple/text_2.svg @@ -0,0 +1,28 @@ + + + + Example text01 + + + Plain text Roboto + + Plain text Verdana + + + Bold text Verdana + + + + + + Stroked bold line + Line 3 + + \ No newline at end of file diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index 3a76400e2ae9..eca788344470 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -16,6 +16,7 @@ const List assetNames = [ 'assets/simple/group_fill_opacity.svg', 'assets/simple/group_opacity.svg', 'assets/simple/text.svg', + 'assets/simple/text_2.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', 'assets/simple/male.svg', diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 8600e8adf52e..82d70ecbc5b8 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -231,7 +231,7 @@ void _appendParagraphs(ParagraphBuilder fill, ParagraphBuilder stroke, stroke ..pushStyle(style.textStyle.toFlutterTextStyle( foregroundOverride: - style.stroke == null ? _transparentStroke : style.stroke)) + DrawablePaint.isEmpty(style.stroke) ? _transparentStroke : style.stroke)) ..addText(text); } @@ -244,30 +244,64 @@ Paragraph _finishParagraph(ParagraphBuilder paragraphBuilder) { return paragraph; } -void _paragraphParser( +Drawable _paragraphParser( ParagraphBuilder fill, ParagraphBuilder stroke, + Offset parentOffset, + DrawableTextAnchorPosition textAnchor, DrawableDefinitionServer definitions, Rect bounds, XmlNode parent, DrawableStyle style) { + final List children = []; + Offset currentOffset = Offset(parentOffset.dx, parentOffset.dy); for (XmlNode child in parent.children) { switch (child.nodeType) { case XmlNodeType.CDATA: + _appendParagraphs(fill, stroke, child.text, style); + break; case XmlNodeType.TEXT: - _appendParagraphs(fill, stroke, child.text, style); + if (child.text.trim().isNotEmpty) { + _appendParagraphs(fill, stroke, child.text.trim(), style); + } break; case XmlNodeType.ELEMENT: final DrawableStyle childStyle = parseStyle(child, definitions, bounds, style); - _paragraphParser(fill, stroke, definitions, bounds, child, childStyle); + final ParagraphBuilder fill = ParagraphBuilder(ParagraphStyle()); + final ParagraphBuilder stroke = ParagraphBuilder(ParagraphStyle()); + final String x = getAttribute(child, 'x', def: null); + final String y = getAttribute(child, 'y', def: null); + final Offset staticOffset = Offset(x!=null ? double.parse(x) : null, + y!=null ? double.parse(y) : null); + final Offset relativeOffset = Offset(double.parse(getAttribute(child, 'dx', def: '0')), + double.parse(getAttribute(child, 'dy', def: '0'))); + final Offset offset = Offset(staticOffset.dx ?? (currentOffset.dx + relativeOffset.dx), + staticOffset.dy ?? (currentOffset.dy + relativeOffset.dy)); + final Drawable drawable = _paragraphParser(fill, stroke, offset, textAnchor, definitions, + bounds, child, childStyle); fill.pop(); stroke.pop(); + children.add(drawable); + if (drawable is DrawableText){ + drawable.fill.layout(ParagraphConstraints(width: double.infinity)); + currentOffset = Offset(currentOffset.dx + drawable.fill.maxIntrinsicWidth, currentOffset.dy); + } break; default: break; } } + children.add(DrawableText( + _finishParagraph(fill), + _finishParagraph(stroke), + parentOffset, + textAnchor, + )); + if (children.length==1){ + return children.elementAt(0); + } + return DrawableGroup(children, style); } Drawable parseSvgText(XmlElement el, DrawableDefinitionServer definitions, @@ -283,25 +317,9 @@ Drawable parseSvgText(XmlElement el, DrawableDefinitionServer definitions, final DrawableTextAnchorPosition textAnchor = parseTextAnchor(getAttribute(el, 'text-anchor', def: 'start')); - if (el.children.length == 1) { - _appendParagraphs(fill, stroke, el.text, style); + return _paragraphParser(fill, stroke, offset, textAnchor, definitions, bounds, el, style); - return DrawableText( - _finishParagraph(fill), - _finishParagraph(stroke), - offset, - textAnchor, - ); - } - _paragraphParser(fill, stroke, definitions, bounds, el, style); - - return DrawableText( - _finishParagraph(fill), - _finishParagraph(stroke), - offset, - textAnchor, - ); } /// Parses an SVG element. @@ -355,14 +373,43 @@ DrawableStyle parseStyle( groupOpacity: parseOpacity(el), clipPath: parseClipPath(el, definitions), textStyle: DrawableTextStyle( - fontFamily: getAttribute(el, 'font-family'), + fontFamily: getAttribute(el, 'font-family', def: null), + fontWeight: getFontWeightByName(getAttribute(el, 'font-weight', def: null)), fontSize: parseFontSize(getAttribute(el, 'font-size'), parentValue: parentStyle?.textStyle?.fontSize), - height: -1.0, ), ); } +FontWeight getFontWeightByName(String fontWeight){ + if (fontWeight==null) { + return null; + } + switch(fontWeight){ + case '100': + return FontWeight.w100; + case '200': + return FontWeight.w200; + case '300': + return FontWeight.w300; + case 'normal': + case '400': + return FontWeight.w400; + case '500': + return FontWeight.w500; + case '600': + return FontWeight.w600; + case 'bold': + case '700': + return FontWeight.bold; + case '800': + return FontWeight.w700; + case '900': + return FontWeight.w800; + } + throw UnsupportedError('font-weight $fontWeight is not supported'); +} + Future _resolveImage(String href) async { if (href == null || href == '') { return null; diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index b4885e707cf0..c262d7a678da 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -418,12 +418,14 @@ class DrawableText implements Drawable { assert(offset != null); switch (anchor) { case DrawableTextAnchorPosition.middle: - return Offset(offset.dx - paragraph.minIntrinsicWidth / 2, offset.dy); + return Offset(offset.dx - paragraph.minIntrinsicWidth / 2, offset.dy-paragraph.height); break; case DrawableTextAnchorPosition.end: - return Offset(offset.dx - paragraph.minIntrinsicWidth, offset.dy); + return Offset(offset.dx - paragraph.minIntrinsicWidth, offset.dy-paragraph.height); break; case DrawableTextAnchorPosition.start: + return Offset(offset.dx, offset.dy-paragraph.alphabeticBaseline); + break; default: return offset; break; From fc05713285d45e27c3faf510801933d2c4f722c8 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 30 Dec 2018 16:06:46 -0800 Subject: [PATCH 201/512] update goldens --- third_party/golden/simple/text.png | Bin 451 -> 457 bytes third_party/golden/simple/text_2.png | Bin 0 -> 885 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 third_party/golden/simple/text_2.png diff --git a/third_party/golden/simple/text.png b/third_party/golden/simple/text.png index fbf7a2c3bfdbeab73501a8b1f051c995aef51768..7dd5cc450ad9393eb184d8f0d298b5bfeafb19be 100644 GIT binary patch literal 457 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>kesKBV@SoEw|6(@9yVZbb+o!5ck7sQmGF9H{zW3|F6~ii5Hva#yY^A@fo3Tu zDQ2Jvq=Sa*yYJ*Z-}!!X`hlvx zsi#xFHJQ$Netv%J!!u#`U-L3KDhRM(A?`g}buxdQ&WA7e&%Igy{nuZ{8fWYZv1!I8 sw(W66U6SCBS088WB|RKKIv&KFVdQ&MBb@0NrhFa{vGU literal 451 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>pj@t}i(^Q|oVRy3W*&B6XuBAELGIQu=PKd#%KVE&)?KRUJouyKbKKfT&mTCS zRqSO1nm{@@@LKo!>%yGdZzK!se%l?}m75%+w|V)2pLg<-YtG6srmG2XFf}TWNW6Z- z`2XsrGjRoc$3K2gPoFc>oP(v&K>!O;a5ZI8`nre@AKn>%ZrA+L>Y%{E(nKVJUX<4B-HR z8jh3>1_ow%PZ!6KiaBrZI_61-%CLRN7hr9Y5-17O3<=Skuqq_=Vh49a6^8}G^n}U9 z1r0?VU2zOoxi7f|vUKfHSk&zxz_&2x%%L{||2JO!cw=L|{mD&AwUwXmZMM^1Jo5%8 z&^|K2-RxtJKUQ3v+>rV;>pHWU?{#Ip{>Xb?dbjP?e7Y5POuKs?gN`w4V^foZqvL`F z3IPEE8X6oTA}m~7OsqJCotFPEs;;~DG~@L1o10%2iHm=pd)x+Op4)QyTOYn;7QK%P zUwrV<+Q0K7e*d1#uai;z=DmK^vdz&?w|-51%grQ;-Q-rkd{aw%|Gxg$XO10I@ceYW z`{eojJ@@S1?b+nH>1*7kjTh(b-r?a_H!tr@Y3%Kz$G`tK&NKQeGtKb!d+`@MY$p#o zx|y#_|MB>H@ZVGS>-#RH%+b!zTUTo4nOFBCb6wuP+q0zqe$4*=ySivnPOj?h+mqkC z_-^u8E!^z>tSmY6_x00OzmLg3+gn#X@8N@wA<5^A+W(&}`^Rdv_T8P6AKqwG_wPG* zaqG7q&GXgH_uEChe{(K#)Aqjx<>m5Q(%SFW?w;}YujmJW#y( z_|4zXPT#wBt={opX^HO7g@1XKt(Q-JUV8rAE2FpX*Zhi^J-GyHkVo8TJ=E{F{Pf=X zX-hoqD)-&HnfX2Y+McafZ~l9KRI1;2S84LA-CL@d>~ZF2T2lSq(YDu+u!W5hUJ}HdQabgxSp Date: Mon, 31 Dec 2018 00:02:25 -0800 Subject: [PATCH 202/512] v0.9.0 --- third_party/CHANGELOG.md | 4 ++++ third_party/example/pubspec.lock | 2 +- third_party/pubspec.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index cd954644a615..7d5d48cc68c4 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 0.9.0 + +- **BREAKING** Improvements to text positioning. Thanks to @krispypen! + ## 0.8.3 - Implement support for `clipPath` outside of `defs` eleemnts. diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index 3a688b3a0a96..75bde42f3e71 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.8.3" + version: "0.9.0" meta: dependency: transitive description: diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 51eef9d8923f..aace2e6be59f 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.8.3 +version: 0.9.0 dependencies: path_drawing: ^0.4.0 From 824786df8490ff6ea75cf65ad518a53dbfd0e3c4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 31 Dec 2018 00:57:03 -0800 Subject: [PATCH 203/512] Text improvements (#95) * text improvements -need goldens * add golden, clean up analysis --- third_party/CHANGELOG.md | 21 ++-- third_party/example/assets/simple/text_3.svg | 11 +++ third_party/example/pubspec.lock | 2 +- third_party/golden/simple/text_3.png | Bin 0 -> 441 bytes third_party/lib/src/svg_parser.dart | 96 ++++++++++++------- third_party/lib/src/utilities/http.dart | 1 + third_party/lib/src/vector_drawable.dart | 47 +++++++-- third_party/pubspec.yaml | 2 +- 8 files changed, 126 insertions(+), 54 deletions(-) create mode 100644 third_party/example/assets/simple/text_3.svg create mode 100644 third_party/golden/simple/text_3.png diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 7d5d48cc68c4..75648b8acaf2 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 0.9.0+1 + +- Fix inheritance issues with `text-anchor`. +- Fix a few inconsistencies in text anchor processing/positioning. + ## 0.9.0 - **BREAKING** Improvements to text positioning. Thanks to @krispypen! @@ -55,7 +60,7 @@ ## 0.6.3 - Consume updated version of path_drawing. -- Fix bug with fill-rule inheritence + example to test. +- Fix bug with fill-rule inheritance + example to test. ## 0.6.2 @@ -64,7 +69,7 @@ ## 0.6.1 -- Fixed an issue with stroke and fill inheritence (and added test) +- Fixed an issue with stroke and fill inheritance (and added test) - General formatting/analyzer cleanup ## 0.6.0 @@ -82,8 +87,8 @@ - Create a new class to encapsulate `Paint` and assist with inheriting all painting properties. - Fixes regression introduced in v0.5.2 where some previously working - inheritence stopped working. -- Support more complex stroke/fill property inheritence. + inheritance stopped working. +- Support more complex stroke/fill property inheritance. ## 0.5.4 @@ -170,7 +175,7 @@ ## 0.2.0 -- Fix bug(s) in inheritence (better rendering of Ghostscript_Tiger.svg) +- Fix bug(s) in inheritance (better rendering of Ghostscript_Tiger.svg) - Support for ``s - Refactoring of how gradients are handled to enable clipPaths - Refactor of SVG shape -> path logic @@ -188,20 +193,20 @@ - Add more unit tests and rendering tests (!). - Add top level flutter_svg.dart. - Fix bugs found in transform matrix logic for skewX and skewY. -- Minor improvements in handling inheritence for PathFillType. +- Minor improvements in handling inheritance for PathFillType. - Support gradient spread types (TileModes in Flutter). ## 0.1.2 - Bump to path_drawing 0.2.3 (fix arc defect). - Handle 'none' in dasharray without throwing exception. -- Better handling of inheritence and 'none' in fill/stroke/dasharray +- Better handling of inheritance and 'none' in fill/stroke/dasharray ## 0.1.1 - Handle opacity on groups and inherited/blended opacity. - Fixes elements that have both opacity and stroke-opacity or fill-opacity. -- Improvements for inheritence. +- Improvements for inheritance. - Fixes related to unspecified fills on shapes. ## 0.1.0 diff --git a/third_party/example/assets/simple/text_3.svg b/third_party/example/assets/simple/text_3.svg new file mode 100644 index 000000000000..38fee3d76840 --- /dev/null +++ b/third_party/example/assets/simple/text_3.svg @@ -0,0 +1,11 @@ + + + + + + + platform + flutter|dart vm + + \ No newline at end of file diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index 75bde42f3e71..bd6217b714c5 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.9.0" + version: "0.9.0+1" meta: dependency: transitive description: diff --git a/third_party/golden/simple/text_3.png b/third_party/golden/simple/text_3.png new file mode 100644 index 0000000000000000000000000000000000000000..a27ede11fd5b5f9a7d872458eca3a272d1023b4f GIT binary patch literal 441 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>pj@)2i(^Q|oVRxjvyK=DI9x0|VF)(A7EHg#e4t)U zz=MNDh^eu~LBa6N?|-l3*FS7AL e3DkaI<{ySvo7HC|@_VcUnda&0=d#Wzp$PzLQ+bmB literal 0 HcmV?d00001 diff --git a/third_party/lib/src/svg_parser.dart b/third_party/lib/src/svg_parser.dart index 82d70ecbc5b8..bbc80f83a8b1 100644 --- a/third_party/lib/src/svg_parser.dart +++ b/third_party/lib/src/svg_parser.dart @@ -230,8 +230,9 @@ void _appendParagraphs(ParagraphBuilder fill, ParagraphBuilder stroke, stroke ..pushStyle(style.textStyle.toFlutterTextStyle( - foregroundOverride: - DrawablePaint.isEmpty(style.stroke) ? _transparentStroke : style.stroke)) + foregroundOverride: DrawablePaint.isEmpty(style.stroke) + ? _transparentStroke + : style.stroke)) ..addText(text); } @@ -245,20 +246,20 @@ Paragraph _finishParagraph(ParagraphBuilder paragraphBuilder) { } Drawable _paragraphParser( - ParagraphBuilder fill, - ParagraphBuilder stroke, - Offset parentOffset, - DrawableTextAnchorPosition textAnchor, - DrawableDefinitionServer definitions, - Rect bounds, - XmlNode parent, - DrawableStyle style) { + ParagraphBuilder fill, + ParagraphBuilder stroke, + Offset parentOffset, + DrawableDefinitionServer definitions, + Rect bounds, + XmlNode parent, + DrawableStyle style, +) { final List children = []; Offset currentOffset = Offset(parentOffset.dx, parentOffset.dy); for (XmlNode child in parent.children) { switch (child.nodeType) { case XmlNodeType.CDATA: - _appendParagraphs(fill, stroke, child.text, style); + _appendParagraphs(fill, stroke, child.text, style); break; case XmlNodeType.TEXT: if (child.text.trim().isNotEmpty) { @@ -272,20 +273,35 @@ Drawable _paragraphParser( final ParagraphBuilder stroke = ParagraphBuilder(ParagraphStyle()); final String x = getAttribute(child, 'x', def: null); final String y = getAttribute(child, 'y', def: null); - final Offset staticOffset = Offset(x!=null ? double.parse(x) : null, - y!=null ? double.parse(y) : null); - final Offset relativeOffset = Offset(double.parse(getAttribute(child, 'dx', def: '0')), - double.parse(getAttribute(child, 'dy', def: '0'))); - final Offset offset = Offset(staticOffset.dx ?? (currentOffset.dx + relativeOffset.dx), - staticOffset.dy ?? (currentOffset.dy + relativeOffset.dy)); - final Drawable drawable = _paragraphParser(fill, stroke, offset, textAnchor, definitions, - bounds, child, childStyle); + final Offset staticOffset = Offset( + x != null ? double.parse(x) : null, + y != null ? double.parse(y) : null, + ); + final Offset relativeOffset = Offset( + double.parse(getAttribute(child, 'dx', def: '0')), + double.parse(getAttribute(child, 'dy', def: '0')), + ); + final Offset offset = Offset( + staticOffset.dx ?? (currentOffset.dx + relativeOffset.dx), + staticOffset.dy ?? (currentOffset.dy + relativeOffset.dy), + ); + final Drawable drawable = _paragraphParser( + fill, + stroke, + offset, + definitions, + bounds, + child, + childStyle, + ); fill.pop(); stroke.pop(); children.add(drawable); - if (drawable is DrawableText){ + if (drawable is DrawableText) { drawable.fill.layout(ParagraphConstraints(width: double.infinity)); - currentOffset = Offset(currentOffset.dx + drawable.fill.maxIntrinsicWidth, currentOffset.dy); + currentOffset = Offset( + currentOffset.dx + drawable.fill.maxIntrinsicWidth, + currentOffset.dy); } break; default: @@ -296,9 +312,10 @@ Drawable _paragraphParser( _finishParagraph(fill), _finishParagraph(stroke), parentOffset, - textAnchor, + style.textStyle.anchor ?? DrawableTextAnchorPosition.start, + transform: style.transform, )); - if (children.length==1){ + if (children.length == 1) { return children.elementAt(0); } return DrawableGroup(children, style); @@ -309,17 +326,26 @@ Drawable parseSvgText(XmlElement el, DrawableDefinitionServer definitions, final Offset offset = Offset(double.parse(getAttribute(el, 'x', def: '0')), double.parse(getAttribute(el, 'y', def: '0'))); - final DrawableStyle style = parseStyle(el, definitions, bounds, parentStyle); + final DrawableStyle style = parseStyle( + el, + definitions, + bounds, + parentStyle, + needsTransform: true, + ); final ParagraphBuilder fill = ParagraphBuilder(ParagraphStyle()); final ParagraphBuilder stroke = ParagraphBuilder(ParagraphStyle()); - final DrawableTextAnchorPosition textAnchor = - parseTextAnchor(getAttribute(el, 'text-anchor', def: 'start')); - - return _paragraphParser(fill, stroke, offset, textAnchor, definitions, bounds, el, style); - - + return _paragraphParser( + fill, + stroke, + offset, + definitions, + bounds, + el, + style, + ); } /// Parses an SVG element. @@ -374,18 +400,20 @@ DrawableStyle parseStyle( clipPath: parseClipPath(el, definitions), textStyle: DrawableTextStyle( fontFamily: getAttribute(el, 'font-family', def: null), - fontWeight: getFontWeightByName(getAttribute(el, 'font-weight', def: null)), + fontWeight: + getFontWeightByName(getAttribute(el, 'font-weight', def: null)), fontSize: parseFontSize(getAttribute(el, 'font-size'), parentValue: parentStyle?.textStyle?.fontSize), + anchor: parseTextAnchor(getAttribute(el, 'text-anchor', def: 'inherit')), ), ); } -FontWeight getFontWeightByName(String fontWeight){ - if (fontWeight==null) { +FontWeight getFontWeightByName(String fontWeight) { + if (fontWeight == null) { return null; } - switch(fontWeight){ + switch (fontWeight) { case '100': return FontWeight.w100; case '200': diff --git a/third_party/lib/src/utilities/http.dart b/third_party/lib/src/utilities/http.dart index 5a8e24262fd2..ef209eca79cb 100644 --- a/third_party/lib/src/utilities/http.dart +++ b/third_party/lib/src/utilities/http.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:io'; import 'dart:typed_data'; diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index c262d7a678da..48e9904764f8 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -52,7 +52,7 @@ class DrawableStyle { /// Used where 'dasharray' is 'none' /// /// This will not result in a drawing operation, but will clear out - /// inheritence. + /// inheritance. static final CircularIntervalList emptyDashArray = CircularIntervalList(const []); @@ -311,6 +311,7 @@ class DrawableTextStyle { this.height, this.locale, this.textBaseline, + this.anchor, }); factory DrawableTextStyle.merge(DrawableTextStyle a, DrawableTextStyle b) { @@ -335,6 +336,8 @@ class DrawableTextStyle { locale: a.locale ?? b.locale, background: a.background ?? b.background, foreground: a.foreground ?? b.foreground, + // anchor: a.anchor != DrawableTextAnchorPosition.start ? a.anchor ?? b.anchor : b.anchor, + anchor: a.anchor ?? b.anchor, ); } @@ -352,6 +355,7 @@ class DrawableTextStyle { final Locale locale; final DrawablePaint background; final DrawablePaint foreground; + final DrawableTextAnchorPosition anchor; TextStyle toFlutterTextStyle({DrawablePaint foregroundOverride}) { return TextStyle( @@ -374,22 +378,29 @@ class DrawableTextStyle { } @override - String toString() { - return 'DrawableTextStyle{$decoration,$decorationColor,$decorationStyle,$fontWeight,$fontFamily,$fontSize,$fontStyle,$foreground,$background,$letterSpacing,$wordSpacing,$height,$locale,$textBaseline}'; - } + String toString() => + 'DrawableTextStyle{$decoration,$decorationColor,$decorationStyle,$fontWeight,' + '$fontFamily,$fontSize,$fontStyle,$foreground,$background,$letterSpacing,$wordSpacing,$height,' + '$locale,$textBaseline,$anchor}'; } enum DrawableTextAnchorPosition { start, middle, end } // WIP. This only handles very, very minimal use cases right now. class DrawableText implements Drawable { - DrawableText(this.fill, this.stroke, this.offset, this.anchor) - : assert(fill != null || stroke != null); + DrawableText( + this.fill, + this.stroke, + this.offset, + this.anchor, { + this.transform, + }) : assert(fill != null || stroke != null); final Offset offset; final DrawableTextAnchorPosition anchor; final Paragraph fill; final Paragraph stroke; + final Float64List transform; @override bool get hasDrawableContent => @@ -400,12 +411,19 @@ class DrawableText implements Drawable { if (!hasDrawableContent) { return; } + if (transform != null) { + canvas.save(); + canvas.transform(transform); + } if (fill != null) { canvas.drawParagraph(fill, resolveOffset(fill, anchor, offset)); } if (stroke != null) { canvas.drawParagraph(stroke, resolveOffset(stroke, anchor, offset)); } + if (transform != null) { + canvas.restore(); + } } static Offset resolveOffset( @@ -418,13 +436,22 @@ class DrawableText implements Drawable { assert(offset != null); switch (anchor) { case DrawableTextAnchorPosition.middle: - return Offset(offset.dx - paragraph.minIntrinsicWidth / 2, offset.dy-paragraph.height); + return Offset( + offset.dx - paragraph.minIntrinsicWidth / 2, + offset.dy - paragraph.alphabeticBaseline, + ); break; case DrawableTextAnchorPosition.end: - return Offset(offset.dx - paragraph.minIntrinsicWidth, offset.dy-paragraph.height); + return Offset( + offset.dx - paragraph.minIntrinsicWidth, + offset.dy - paragraph.alphabeticBaseline, + ); break; case DrawableTextAnchorPosition.start: - return Offset(offset.dx, offset.dy-paragraph.alphabeticBaseline); + return Offset( + offset.dx, + offset.dy - paragraph.alphabeticBaseline, + ); break; default: return offset; @@ -552,7 +579,7 @@ class DrawableRoot implements Drawable { /// Contains reusable definitions such as gradients and clipPaths. final DrawableDefinitionServer definitions; - /// The [DrawableStyle] for inheritence. + /// The [DrawableStyle] for inheritance. final DrawableStyle style; /// Scales the `canvas` so that the drawing units in this [Drawable] diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index aace2e6be59f..1f36c74ff325 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. author: Dan Field homepage: https://github.com/dnfield/flutter_svg -version: 0.9.0 +version: 0.9.0+1 dependencies: path_drawing: ^0.4.0 From 24dcd58eae47db810d2487535ff1355518f7a85e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 8 Jan 2019 21:35:17 -0800 Subject: [PATCH 204/512] Parsing rewrite (#85) Use push based reader for XML parsing --- third_party/.travis.yml | 2 +- third_party/CHANGELOG.md | 5 + third_party/example/android/.project | 17 + .../org.eclipse.buildship.core.prefs | 2 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + third_party/example/lib/main.dart | 18 +- third_party/example/pubspec.lock | 6 +- .../golden/noto-emoji/emoji_u1f600.png | Bin 9296 -> 9294 bytes third_party/lib/avd.dart | 4 +- third_party/lib/parser.dart | 12 + third_party/lib/src/avd/xml_parsers.dart | 16 +- third_party/lib/src/avd_parser.dart | 16 +- third_party/lib/src/svg/parser_state.dart | 720 ++++++++++++++++++ third_party/lib/src/svg/parsers.dart | 67 +- third_party/lib/src/svg/xml_parsers.dart | 497 +++--------- third_party/lib/src/svg_parser.dart | 464 ----------- third_party/lib/src/utilities/xml.dart | 23 +- third_party/lib/src/vector_drawable.dart | 93 ++- third_party/lib/svg.dart | 30 +- third_party/pubspec.lock | 4 +- third_party/pubspec.yaml | 7 +- third_party/test/vector_drawable_test.dart | 27 + third_party/test/xml_svg_test.dart | 60 +- 23 files changed, 1112 insertions(+), 986 deletions(-) create mode 100644 third_party/example/android/.project create mode 100644 third_party/example/android/.settings/org.eclipse.buildship.core.prefs create mode 100644 third_party/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 third_party/lib/parser.dart create mode 100644 third_party/lib/src/svg/parser_state.dart delete mode 100644 third_party/lib/src/svg_parser.dart create mode 100644 third_party/test/vector_drawable_test.dart diff --git a/third_party/.travis.yml b/third_party/.travis.yml index bc9f40bee859..4244109f5f12 100644 --- a/third_party/.travis.yml +++ b/third_party/.travis.yml @@ -10,7 +10,7 @@ addons: - libstdc++6 - fonts-droid before_script: - - git clone https://github.com/flutter/flutter.git -b dev --single-branch + - git clone https://github.com/flutter/flutter.git -b master --single-branch - ./flutter/bin/flutter doctor - gem install coveralls-lcov script: diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 75648b8acaf2..7c82aa906e03 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 0.10.0 + +- Rewrite parsing to be more space efficient. +- Refactor parsing to enable more output possibilities. + ## 0.9.0+1 - Fix inheritance issues with `text-anchor`. diff --git a/third_party/example/android/.project b/third_party/example/android/.project new file mode 100644 index 000000000000..3964dd3f5b7f --- /dev/null +++ b/third_party/example/android/.project @@ -0,0 +1,17 @@ + + + android + Project android created by Buildship. + + + + + org.eclipse.buildship.core.gradleprojectbuilder + + + + + + org.eclipse.buildship.core.gradleprojectnature + + diff --git a/third_party/example/android/.settings/org.eclipse.buildship.core.prefs b/third_party/example/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 000000000000..e8895216fd3c --- /dev/null +++ b/third_party/example/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,2 @@ +connection.project.dir= +eclipse.preferences.version=1 diff --git a/third_party/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/third_party/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 000000000000..18d981003d68 --- /dev/null +++ b/third_party/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index eca788344470..913d62e3ada4 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -7,15 +7,15 @@ import 'package:flutter_svg/flutter_svg.dart'; const List assetNames = [ // 'assets/notfound.svg', // uncomment to test an asset that doesn't exist. - 'assets/flutter_logo.svg', - 'assets/dart.svg', - 'assets/simple/clip_path_3.svg', - 'assets/simple/clip_path_2.svg', - 'assets/simple/clip_path.svg', - 'assets/simple/fill-rule-inherit.svg', - 'assets/simple/group_fill_opacity.svg', - 'assets/simple/group_opacity.svg', - 'assets/simple/text.svg', + // 'assets/flutter_logo.svg', + // 'assets/dart.svg', + // 'assets/simple/clip_path_3.svg', + // 'assets/simple/clip_path_2.svg', + // 'assets/simple/clip_path.svg', + // 'assets/simple/fill-rule-inherit.svg', + // 'assets/simple/group_fill_opacity.svg', + // 'assets/simple/group_opacity.svg', + // 'assets/simple/text.svg', 'assets/simple/text_2.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', diff --git a/third_party/example/pubspec.lock b/third_party/example/pubspec.lock index bd6217b714c5..12ed520558de 100644 --- a/third_party/example/pubspec.lock +++ b/third_party/example/pubspec.lock @@ -19,7 +19,7 @@ packages: path: ".." relative: true source: path - version: "0.9.0+1" + version: "0.10.0" meta: dependency: transitive description: @@ -73,7 +73,7 @@ packages: name: xml url: "https://pub.dartlang.org" source: hosted - version: "3.2.0" + version: "3.2.5" sdks: - dart: ">=2.0.0-dev.69.0 <3.0.0" + dart: ">2.0.0 <3.0.0" flutter: ">=0.7.3 <2.0.0" diff --git a/third_party/golden/noto-emoji/emoji_u1f600.png b/third_party/golden/noto-emoji/emoji_u1f600.png index 182a392a4aa152c4c3fad9b1853504b9b697e64d..395b86616a2d9ac79343e90556c708d3d4bc77be 100644 GIT binary patch literal 9294 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 diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 5d8298efff37..e869984082fe 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -65,7 +65,7 @@ class Avd { /// Creates a [DrawableRoot] from a string of Android Vector Drawable data. DrawableRoot fromAvdString(String rawSvg, String key) { final XmlElement svg = xml.parse(rawSvg).rootElement; - final DrawableViewport viewBox = parseViewBox(svg); + final DrawableViewport viewBox = parseViewBox(svg.attributes); final List children = svg.children .whereType() .map((XmlElement child) => parseAvdElement(child, viewBox.viewBoxRect)) @@ -152,7 +152,7 @@ class AvdPicture extends SvgPicture { /// Creates a [DrawableRoot] from a string of SVG data. DrawableRoot fromAvdString(String rawSvg, Rect size) { final XmlElement svg = xml.parse(rawSvg).rootElement; - final DrawableViewport viewBox = parseViewBox(svg); + final DrawableViewport viewBox = parseViewBox(svg.attributes); final List children = svg.children .whereType() .map((XmlElement child) => parseAvdElement(child, size)) diff --git a/third_party/lib/parser.dart b/third_party/lib/parser.dart new file mode 100644 index 000000000000..437cf2f69b95 --- /dev/null +++ b/third_party/lib/parser.dart @@ -0,0 +1,12 @@ +import 'dart:async'; + +import 'package:xml/xml.dart' show XmlPushReader; + +import 'src/svg/parser_state.dart'; +import 'src/vector_drawable.dart'; + +class SvgParser { + Future parse(String str, {String key}) async { + return await SvgParserState(XmlPushReader(str), key).parse(); + } +} diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index ded962ac1044..38d850c14dc6 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -11,7 +11,7 @@ import '../utilities/xml.dart'; const String androidNS = 'http://schemas.android.com/apk/res/android'; /// Parses an AVD @android:viewportWidth and @android:viewportHeight attributes to a [Rect]. -DrawableViewport parseViewBox(XmlElement el) { +DrawableViewport parseViewBox(List el) { final String rawWidth = getAttribute(el, 'viewportWidth', def: '', namespace: androidNS); final String rawHeight = @@ -27,7 +27,7 @@ DrawableViewport parseViewBox(XmlElement el) { ); } -Matrix4 parseTransform(XmlElement el) { +Matrix4 parseTransform(List el) { final double rotation = double.parse( getAttribute(el, 'rotation', def: '0', namespace: androidNS)); final double pivotX = @@ -50,7 +50,7 @@ Matrix4 parseTransform(XmlElement el) { ..translate(-pivotX + translateX, -pivotY + translateY); } -DrawablePaint parseStroke(XmlElement el, Rect bounds) { +DrawablePaint parseStroke(List el, Rect bounds) { final String rawStroke = getAttribute(el, 'strokeColor', def: null, namespace: androidNS); if (rawStroke == null) { @@ -68,12 +68,12 @@ DrawablePaint parseStroke(XmlElement el, Rect bounds) { ); } -double parseMiterLimit(XmlElement el) { +double parseMiterLimit(List el) { return double.parse( getAttribute(el, 'strokeMiterLimit', def: '4', namespace: androidNS)); } -StrokeJoin parseStrokeJoin(XmlElement el) { +StrokeJoin parseStrokeJoin(List el) { final String rawStrokeJoin = getAttribute(el, 'strokeLineJoin', def: 'miter', namespace: androidNS); switch (rawStrokeJoin) { @@ -88,7 +88,7 @@ StrokeJoin parseStrokeJoin(XmlElement el) { } } -StrokeCap parseStrokeCap(XmlElement el) { +StrokeCap parseStrokeCap(List el) { final String rawStrokeCap = getAttribute(el, 'strokeLineCap', def: 'butt', namespace: androidNS); switch (rawStrokeCap) { @@ -103,7 +103,7 @@ StrokeCap parseStrokeCap(XmlElement el) { } } -DrawablePaint parseFill(XmlElement el, Rect bounds) { +DrawablePaint parseFill(List el, Rect bounds) { final String rawFill = getAttribute(el, 'fillColor', def: null, namespace: androidNS); if (rawFill == null) { @@ -116,7 +116,7 @@ DrawablePaint parseFill(XmlElement el, Rect bounds) { ); } -PathFillType parsePathFillType(XmlElement el) { +PathFillType parsePathFillType(List el) { final String rawFillType = getAttribute(el, 'fillType', def: 'nonZero', namespace: androidNS); return rawFillType == 'nonZero' ? PathFillType.nonZero : PathFillType.evenOdd; diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index 6d5617888957..b3340d0a5fd5 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -21,13 +21,13 @@ class DrawableAvdPath extends DrawableShape { /// Creates a [DrawableAvdPath] from an XML element factory DrawableAvdPath.fromXml(XmlElement el) { final String d = - getAttribute(el, 'pathData', def: '', namespace: androidNS); + getAttribute(el.attributes, 'pathData', def: '', namespace: androidNS); final Path path = parseSvgPathData(d); assert(path != null); - path.fillType = parsePathFillType(el); - final DrawablePaint stroke = parseStroke(el, path.getBounds()); - final DrawablePaint fill = parseFill(el, path.getBounds()); + path.fillType = parsePathFillType(el.attributes); + final DrawablePaint stroke = parseStroke(el.attributes, path.getBounds()); + final DrawablePaint fill = parseFill(el.attributes, path.getBounds()); return DrawableAvdPath( path, @@ -47,7 +47,7 @@ Drawable parseAvdElement(XmlElement el, Rect bounds) { } // TODO(dnfield): clipPath print('Unhandled element ${el.name.local}'); - return DrawableNoop(el.name.local); + return const DrawableGroup(null, null); } /// Parses an AVD element. @@ -62,10 +62,10 @@ Drawable parseAvdGroup(XmlElement el, Rect bounds) { } } - final Matrix4 transform = parseTransform(el); + final Matrix4 transform = parseTransform(el.attributes); - final DrawablePaint fill = parseFill(el, bounds); - final DrawablePaint stroke = parseStroke(el, bounds); + final DrawablePaint fill = parseFill(el.attributes, bounds); + final DrawablePaint stroke = parseStroke(el.attributes, bounds); return DrawableGroup( children, diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart new file mode 100644 index 000000000000..08286934b333 --- /dev/null +++ b/third_party/lib/src/svg/parser_state.dart @@ -0,0 +1,720 @@ +import 'dart:async'; +import 'dart:collection'; +import 'dart:ui'; + +import 'package:flutter/foundation.dart'; +import 'package:path_drawing/path_drawing.dart'; +import 'package:vector_math/vector_math_64.dart'; +import 'package:xml/xml.dart' + show XmlPushReader, XmlPushReaderNodeType, XmlAttribute; + +import '../utilities/xml.dart'; +import '../vector_drawable.dart'; +import 'colors.dart'; +import 'parsers.dart'; +import 'xml_parsers.dart'; + +final Set _unhandledElements = Set(); + +typedef _ParseFunc = Future Function(SvgParserState parserState); +typedef _PathFunc = Path Function(List attributes); + +const Map _svgElementParsers = { + 'svg': _Elements.svg, + 'g': _Elements.g, + 'a': _Elements.g, // treat as group + 'use': _Elements.use, + 'symbol': _Elements.symbol, + 'radialGradient': _Elements.radialGradient, + 'linearGradient': _Elements.linearGradient, + 'clipPath': _Elements.clipPath, + 'image': _Elements.image, + 'text': _Elements.text, +}; + +const Map svgPathFuncs = { + 'circle': _Paths.circle, + 'path': _Paths.path, + 'rect': _Paths.rect, + 'polygon': _Paths.polygon, + 'polyline': _Paths.polyline, + 'ellipse': _Paths.ellipse, + 'line': _Paths.line, +}; + +Offset _parseCurrentOffset(SvgParserState parserState, Offset lastOffset) { + final String x = parserState.attribute('x', def: null); + final String y = parserState.attribute('y', def: null); + + return Offset( + x != null + ? double.parse(x) + : double.parse(parserState.attribute('dx', def: '0')) + + (lastOffset?.dx ?? 0), + y != null + ? double.parse(y) + : double.parse(parserState.attribute('dy', def: '0')) + + (lastOffset?.dy ?? 0), + ); +} + +class _TextInfo { + const _TextInfo( + this.style, + this.offset, + ); + final DrawableStyle style; + final Offset offset; + + @override + String toString() => '$runtimeType{$offset, $style}'; +} + +class _Elements { + static Future svg(SvgParserState parserState) { + final DrawableViewport viewBox = parseViewBox(parserState.attributes); + + parserState._root = DrawableRoot( + viewBox, + [], + parserState.definitions, + parseStyle(parserState.attributes, parserState.definitions, + viewBox.viewBoxRect, null), + ); + parserState.addGroup(parserState._root); + return null; + } + + static Future g(SvgParserState parserState) { + final DrawableParent parent = parserState.currentGroup; + final DrawableGroup group = DrawableGroup( + [], + parseStyle( + parserState.attributes, + parserState.definitions, + parserState.rootBounds, + parent.style, + needsTransform: true, + ), + ); + if (!parserState.inDefs) { + parent.children.add(group); + } + parserState.addGroup(group); + return null; + } + + static Future symbol(SvgParserState parserState) { + final DrawableParent parent = parserState.currentGroup; + final DrawableGroup group = DrawableGroup( + [], + parseStyle( + parserState.attributes, + parserState.definitions, + null, + parent.style, + needsTransform: true, + ), + ); + parserState.addGroup(group); + return null; + } + + static Future use(SvgParserState parserState) { + final String xlinkHref = getHrefAttribute(parserState.attributes); + final DrawableStyle style = parseStyle( + parserState.attributes, + parserState.definitions, + parserState.rootBounds, + null, + ); + final Matrix4 transform = Matrix4.identity() + ..translate( + double.parse(parserState.attribute('x', def: '0')), + double.parse(parserState.attribute('y', def: '0')), + ); + final DrawableStyleable ref = + parserState.definitions.getDrawable('url($xlinkHref)'); + final DrawableParent parent = parserState.currentGroup; + final DrawableGroup group = DrawableGroup( + [ref.mergeStyle(style)], + DrawableStyle(transform: transform.storage), + ); + parent.children.add(group); + return null; + } + + static Future parseStops( + XmlPushReader reader, List colors, List offsets) { + final int depth = reader.depth; + + while (reader.read() && depth < reader.depth) { + final String rawOpacity = getAttribute( + reader.attributes, + 'stop-opacity', + def: '1', + ); + colors.add(parseColor(getAttribute(reader.attributes, 'stop-color')) + .withOpacity(double.parse(rawOpacity))); + + final String rawOffset = getAttribute( + reader.attributes, + 'offset', + def: '0%', + ); + offsets.add(parseDecimalOrPercentage(rawOffset)); + } + return null; + } + + static Future radialGradient(SvgParserState parserState) { + final String gradientUnits = getAttribute( + parserState.attributes, 'gradientUnits', + def: 'objectBoundingBox'); + final bool isObjectBoundingBox = gradientUnits == 'objectBoundingBox'; + + final String rawCx = parserState.attribute('cx', def: '50%'); + final String rawCy = parserState.attribute('cy', def: '50%'); + final String rawR = parserState.attribute('r', def: '50%'); + final String rawFx = parserState.attribute('fx', def: rawCx); + final String rawFy = parserState.attribute('fy', def: rawCy); + final TileMode spreadMethod = parseTileMode(parserState.attributes); + final String id = buildUrlIri(parserState.attributes); + final Matrix4 originalTransform = parseTransform( + parserState.attribute('gradientTransform', def: null), + ); + + final List offsets = []; + final List colors = []; + parseStops(parserState._reader, colors, offsets); + + final Rect rootBounds = Rect.fromLTRB( + parserState.rootBounds.left, + parserState.rootBounds.top, + parserState.rootBounds.right, + parserState.rootBounds.bottom, + ); + + final PaintServer shaderFunc = (Rect bounds) { + double cx, cy, r, fx, fy; + Matrix4 transform = originalTransform?.clone() ?? Matrix4.identity(); + + if (isObjectBoundingBox) { + final Matrix4 scale = + affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); + final Matrix4 translate = + affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); + transform = translate.multiplied(scale)..multiply(transform); + + cx = parseDecimalOrPercentage(rawCx); + cy = parseDecimalOrPercentage(rawCy); + r = parseDecimalOrPercentage(rawR); + fx = parseDecimalOrPercentage(rawFx); + fy = parseDecimalOrPercentage(rawFy); + } else { + cx = isPercentage(rawCx) + ? parsePercentage(rawCx) * rootBounds.width + rootBounds.left + : double.parse(rawCx); + cy = isPercentage(rawCy) + ? parsePercentage(rawCy) * rootBounds.height + rootBounds.top + : double.parse(rawCy); + r = isPercentage(rawR) + ? parsePercentage(rawR) * + ((rootBounds.height + rootBounds.width) / 2) + : double.parse(rawR); + fx = isPercentage(rawFx) + ? parsePercentage(rawFx) * rootBounds.width + rootBounds.left + : double.parse(rawFx); + fy = isPercentage(rawFy) + ? parsePercentage(rawFy) * rootBounds.height + rootBounds.top + : double.parse(rawFy); + } + + final Offset center = Offset(cx, cy); + final Offset focal = + (fx != cx || fy != cy) ? Offset(fx, fy) : Offset(cx, cy); + + return Gradient.radial( + center, + r, + colors, + offsets, + spreadMethod, + transform?.storage, + focal, + 0.0, + ); + }; + + parserState.definitions.addPaintServer( + id, + shaderFunc, + ); + return null; + } + + static Future linearGradient(SvgParserState parserState) { + final String gradientUnits = getAttribute( + parserState.attributes, 'gradientUnits', + def: 'objectBoundingBox'); + final bool isObjectBoundingBox = gradientUnits == 'objectBoundingBox'; + + final String x1 = parserState.attribute('x1', def: '0%'); + final String x2 = parserState.attribute('x2', def: '100%'); + final String y1 = parserState.attribute('y1', def: '0%'); + final String y2 = parserState.attribute('y2', def: '0%'); + final String id = buildUrlIri(parserState.attributes); + final Matrix4 originalTransform = parseTransform( + parserState.attribute('gradientTransform', def: null), + ); + final TileMode spreadMethod = parseTileMode(parserState.attributes); + + final List colors = []; + final List offsets = []; + parseStops(parserState._reader, colors, offsets); + final Rect rootBounds = Rect.fromLTRB( + parserState.rootBounds.left, + parserState.rootBounds.top, + parserState.rootBounds.right, + parserState.rootBounds.bottom, + ); + + final PaintServer shaderFunc = (Rect bounds) { + Vector3 from, to; + Matrix4 transform = originalTransform?.clone() ?? Matrix4.identity(); + + if (isObjectBoundingBox) { + final Matrix4 scale = + affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); + final Matrix4 translate = + affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); + transform = translate.multiplied(scale)..multiply(transform); + + final Offset fromOffset = Offset( + parseDecimalOrPercentage(x1), + parseDecimalOrPercentage(y1), + ); + final Offset toOffset = Offset( + parseDecimalOrPercentage(x2), + parseDecimalOrPercentage(y2), + ); + + from = Vector3( + fromOffset.dx, + fromOffset.dy, + 0.0, + ); + to = Vector3( + toOffset.dx, + toOffset.dy, + 0.0, + ); + } else { + final Offset fromOffset = Offset( + isPercentage(x1) + ? parsePercentage(x1) * rootBounds.width + rootBounds.left + : double.parse(x1), + isPercentage(y1) + ? parsePercentage(y1) * rootBounds.height + rootBounds.top + : double.parse(y1), + ); + + final Offset toOffset = Offset( + isPercentage(x2) + ? parsePercentage(x2) * rootBounds.width + rootBounds.left + : double.parse(x2), + isPercentage(y2) + ? parsePercentage(y2) * rootBounds.height + rootBounds.top + : double.parse(y2), + ); + + from = Vector3(fromOffset.dx, fromOffset.dy, 0.0); + to = Vector3(toOffset.dx, toOffset.dy, 0.0); + } + + if (transform != null) { + from = transform.transform3(from); + to = transform.transform3(to); + } + + return Gradient.linear( + Offset(from.x, from.y), + Offset(to.x, to.y), + colors, + offsets, + spreadMethod, + ); + }; + + parserState.definitions.addPaintServer( + id, + shaderFunc, + ); + return null; + } + + static Future clipPath(SvgParserState parserState) { + final String id = buildUrlIri(parserState.attributes); + + final List paths = []; + Path currentPath; + final int depth = parserState._reader.depth; + while (parserState._reader.read() && depth < parserState._reader.depth) { + final _PathFunc pathFn = svgPathFuncs[parserState._reader.name.local]; + if (pathFn != null) { + final Path nextPath = applyTransformIfNeeded( + pathFn(parserState.attributes), + parserState.attributes, + ); + nextPath.fillType = parseFillRule(parserState.attributes, 'clip-rule'); + if (currentPath != null && nextPath.fillType != currentPath.fillType) { + currentPath = nextPath; + paths.add(currentPath); + } else if (currentPath == null) { + currentPath = nextPath; + paths.add(currentPath); + } else { + currentPath.addPath(nextPath, Offset.zero); + } + } else if (parserState._reader.name.local == 'use') { + final String xlinkHref = getHrefAttribute(parserState.attributes); + final DrawableStyleable definitionDrawable = + parserState.definitions.getDrawable('url($xlinkHref)'); + + void extractPathsFromDrawable(Drawable target) { + if (target is DrawableShape) { + paths.add(target.path); + } else if (target is DrawableGroup) { + target.children.forEach(extractPathsFromDrawable); + } + } + + extractPathsFromDrawable(definitionDrawable); + } else { + FlutterError.reportError(FlutterErrorDetails( + exception: UnsupportedError( + 'Unsupported clipPath child ${parserState._reader.name.local}'), + informationCollector: (StringBuffer buff) { + buff.writeln( + 'The element contained an unsupported child ${parserState._reader.name.local}'); + if (parserState.key != null) { + buff.writeln(); + buff.writeln('Picture key: ${parserState.key}'); + } + }, + library: 'SVG', + context: 'in _Element.clipPath', + )); + } + } + parserState.definitions.addClipPath(id, paths); + return null; + } + + static Future image(SvgParserState parserState) async { + final String href = getHrefAttribute(parserState.attributes); + final Offset offset = Offset( + double.parse(parserState.attribute('x', def: '0')), + double.parse(parserState.attribute('y', def: '0')), + ); + final Size size = Size( + double.parse(parserState.attribute('width', def: '0')), + double.parse(parserState.attribute('height', def: '0')), + ); + final Image image = await resolveImage(href); + parserState.currentGroup.children.add( + DrawableRasterImage(image, offset, size: size), + ); + } + + static Future text(SvgParserState parserState) async { + assert(parserState != null); + assert(parserState.currentGroup != null); + // , -> Collect styles + // TBD - looks like Inkscape supports it, but no browser does. + // XmlPushReaderNodeType.TEXT/CDATA -> DrawableText + // Track the style(s) and offset(s) for and elements + final Queue<_TextInfo> textInfos = ListQueue<_TextInfo>(); + double lastTextWidth = 0; + final int depth = parserState._reader.depth; + do { + switch (parserState._reader.nodeType) { + case XmlPushReaderNodeType.CDATA: + case XmlPushReaderNodeType.TEXT: + final String value = parserState._reader.value.trim(); + if (value.isEmpty) { + continue; + } + assert(textInfos.isNotEmpty); + final _TextInfo lastTextInfo = textInfos.last; + final Paragraph fill = createParagraph( + value, + lastTextInfo.style, + lastTextInfo.style.fill, + ); + final Paragraph stroke = createParagraph( + value, + lastTextInfo.style, + DrawablePaint.isEmpty(lastTextInfo.style.stroke) + ? transparentStroke + : lastTextInfo.style.stroke, + ); + parserState.currentGroup.children.add(DrawableText( + fill, + stroke, + lastTextInfo.offset, + lastTextInfo.style.textStyle.anchor ?? + DrawableTextAnchorPosition.start, + transform: lastTextInfo.style.transform, + )); + lastTextWidth = fill.maxIntrinsicWidth; + break; + case XmlPushReaderNodeType.ELEMENT: + _TextInfo lastTextInfo; + if (textInfos.isNotEmpty) { + lastTextInfo = textInfos.last; + } + final Offset currentOffset = _parseCurrentOffset( + parserState, lastTextInfo?.offset?.translate(lastTextWidth, 0)); + textInfos.add(_TextInfo( + parseStyle( + parserState.attributes, + parserState.definitions, + parserState.rootBounds, + lastTextInfo?.style ?? parserState.currentGroup.style, + needsTransform: true, + ), + currentOffset, + )); + break; + case XmlPushReaderNodeType.END_ELEMENT: + textInfos.removeLast(); + break; + default: + break; + } + } while (parserState._reader.read() && depth <= parserState._reader.depth); + } +} + +class _Paths { + static Path circle(List attributes) { + final double cx = double.parse(getAttribute(attributes, 'cx', def: '0')); + final double cy = double.parse(getAttribute(attributes, 'cy', def: '0')); + final double r = double.parse(getAttribute(attributes, 'r', def: '0')); + final Rect oval = Rect.fromCircle(center: Offset(cx, cy), radius: r); + return Path()..addOval(oval); + } + + static Path path(List attributes) { + final String d = getAttribute(attributes, 'd'); + return parseSvgPathData(d); + } + + static Path rect(List attributes) { + final double x = double.parse(getAttribute(attributes, 'x', def: '0')); + final double y = double.parse(getAttribute(attributes, 'y', def: '0')); + final double w = double.parse(getAttribute(attributes, 'width', def: '0')); + final double h = double.parse(getAttribute(attributes, 'height', def: '0')); + final Rect rect = Rect.fromLTWH(x, y, w, h); + String rxRaw = getAttribute(attributes, 'rx', def: null); + String ryRaw = getAttribute(attributes, 'ry', def: null); + rxRaw ??= ryRaw; + ryRaw ??= rxRaw; + + if (rxRaw != null && rxRaw != '') { + final double rx = double.parse(rxRaw); + final double ry = double.parse(ryRaw); + + return Path()..addRRect(RRect.fromRectXY(rect, rx, ry)); + } + + return Path()..addRect(rect); + } + + static Path polygon(List attributes) { + return parsePathFromPoints(attributes, true); + } + + static Path polyline(List attributes) { + return parsePathFromPoints(attributes, false); + } + + static Path parsePathFromPoints(List attributes, bool close) { + final String points = getAttribute(attributes, 'points'); + if (points == '') { + return null; + } + final String path = 'M$points${close ? 'z' : ''}'; + + return parseSvgPathData(path); + } + + static Path ellipse(List attributes) { + final double cx = double.parse(getAttribute(attributes, 'cx', def: '0')); + final double cy = double.parse(getAttribute(attributes, 'cy', def: '0')); + final double rx = double.parse(getAttribute(attributes, 'rx', def: '0')); + final double ry = double.parse(getAttribute(attributes, 'ry', def: '0')); + + final Rect r = Rect.fromLTWH(cx - rx, cy - ry, rx * 2, ry * 2); + return Path()..addOval(r); + } + + static Path line(List attributes) { + final double x1 = double.parse(getAttribute(attributes, 'x1', def: '0')); + final double x2 = double.parse(getAttribute(attributes, 'x2', def: '0')); + final double y1 = double.parse(getAttribute(attributes, 'y1', def: '0')); + final double y2 = double.parse(getAttribute(attributes, 'y2', def: '0')); + + return Path() + ..moveTo(x1, y1) + ..lineTo(x2, y2); + } +} + +class _SvgGroupTuple { + _SvgGroupTuple(this.name, this.drawable); + + final String name; + final DrawableParent drawable; +} + +class SvgParserState { + SvgParserState(this._reader, this.key) : assert(_reader != null); + + final XmlPushReader _reader; + final String key; + final DrawableDefinitionServer definitions = DrawableDefinitionServer(); + final Queue<_SvgGroupTuple> parentDrawables = ListQueue<_SvgGroupTuple>(10); + DrawableRoot _root; + bool inDefs = false; + + Future parse() async { + while (_reader.read()) { + switch (_reader.nodeType) { + case XmlPushReaderNodeType.ELEMENT: + if (startElement()) { + continue; + } + final _ParseFunc parseFunc = _svgElementParsers[_reader.name.local]; + await parseFunc?.call(this); + assert(() { + if (parseFunc == null) { + unhandledElement(); + } + return true; + }()); + break; + case XmlPushReaderNodeType.END_ELEMENT: + endElement(); + break; + // comments, doctype, and process instructions are ignored. + case XmlPushReaderNodeType.COMMENT: + case XmlPushReaderNodeType.DOCUMENT_TYPE: + case XmlPushReaderNodeType.PROCESSING: + // CDATA and TEXT are handled by the `` parser + case XmlPushReaderNodeType.TEXT: + case XmlPushReaderNodeType.CDATA: + break; + } + } + return _root; + } + + List get attributes => _reader.attributes; + + String attribute(String name, {String def, String namespace}) => + getAttribute(attributes, name, def: def, namespace: namespace); + + DrawableParent get currentGroup { + assert(parentDrawables != null); + assert(parentDrawables.isNotEmpty); + return parentDrawables.last.drawable; + } + + Rect get rootBounds { + assert(_root != null, 'Cannot get rootBounds with null root'); + assert(_root.viewport != null); + return _root.viewport.viewBoxRect; + } + + bool checkForIri(DrawableStyleable drawable) { + final String iri = buildUrlIri(attributes); + if (iri != emptyUrlIri) { + definitions.addDrawable(iri, drawable); + return true; + } + return false; + } + + void addGroup(DrawableParent drawable) { + parentDrawables.addLast(_SvgGroupTuple(_reader.name.local, drawable)); + checkForIri(drawable); + } + + bool addShape() { + final _PathFunc pathFunc = svgPathFuncs[_reader.name.local]; + if (pathFunc == null) { + return false; + } + + final DrawableParent parent = parentDrawables.last.drawable; + final DrawableStyle parentStyle = parent.style; + final Path path = pathFunc(attributes); + final DrawableStyleable drawable = DrawableShape( + path, + parseStyle( + attributes, + definitions, + path.getBounds(), + parentStyle, + ), + transform: parseTransform(getAttribute(attributes, 'transform'))?.storage, + ); + final bool isIri = checkForIri(drawable); + if (!inDefs || !isIri) { + parent.children.add(drawable); + } + return true; + } + + bool startElement() { + if (_reader.name.local == 'defs') { + inDefs = true; + return true; + } + return addShape(); + } + + void endElement() { + if (_reader.name.local == parentDrawables.last.name) { + parentDrawables.removeLast(); + } + if (_reader.name.local == 'defs') { + inDefs = false; + } + } + + void unhandledElement() { + if (_reader.name.local == 'style') { + FlutterError.reportError(FlutterErrorDetails( + exception: UnimplementedError( + 'The diff --git a/third_party/example/assets/simple/radial_gradient_xlink.svg b/third_party/example/assets/simple/radial_gradient_xlink.svg new file mode 100644 index 000000000000..ea3f3cd0ba1e --- /dev/null +++ b/third_party/example/assets/simple/radial_gradient_xlink.svg @@ -0,0 +1,24 @@ + + + + Example radgrad01 - fill a rectangle by referencing a + radial gradient paint server + + + + + + + + + + + + + + + + + diff --git a/third_party/golden/simple/linear_gradient_xlink.png b/third_party/golden/simple/linear_gradient_xlink.png new file mode 100644 index 0000000000000000000000000000000000000000..729a425bf0b5402c22b36d0ce9dcfa544e147b75 GIT binary patch literal 4748 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 D^k(2s literal 0 HcmV?d00001 diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index 7e742ee342a8..e9a9d0a5100c 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -186,69 +186,63 @@ class _Elements { final List offsets = []; final List colors = []; - parseStops(parserState._reader, colors, offsets); - final Rect rootBounds = Rect.fromLTRB( - parserState.rootBounds.left, - parserState.rootBounds.top, - parserState.rootBounds.right, - parserState.rootBounds.bottom, - ); - - final PaintServer shaderFunc = (Rect bounds) { - double cx, cy, r, fx, fy; - Matrix4 transform = originalTransform?.clone() ?? Matrix4.identity(); - - if (isObjectBoundingBox) { - final Matrix4 scale = - affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); - final Matrix4 translate = - affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); - transform = translate.multiplied(scale)..multiply(transform); - - cx = parseDecimalOrPercentage(rawCx); - cy = parseDecimalOrPercentage(rawCy); - r = parseDecimalOrPercentage(rawR); - fx = parseDecimalOrPercentage(rawFx); - fy = parseDecimalOrPercentage(rawFy); - } else { - cx = isPercentage(rawCx) - ? parsePercentage(rawCx) * rootBounds.width + rootBounds.left - : double.parse(rawCx); - cy = isPercentage(rawCy) - ? parsePercentage(rawCy) * rootBounds.height + rootBounds.top - : double.parse(rawCy); - r = isPercentage(rawR) - ? parsePercentage(rawR) * - ((rootBounds.height + rootBounds.width) / 2) - : double.parse(rawR); - fx = isPercentage(rawFx) - ? parsePercentage(rawFx) * rootBounds.width + rootBounds.left - : double.parse(rawFx); - fy = isPercentage(rawFy) - ? parsePercentage(rawFy) * rootBounds.height + rootBounds.top - : double.parse(rawFy); - } + if (parserState._reader.isEmptyElement) { + final String href = getHrefAttribute(parserState.attributes); + final DrawableRadialGradient ref = parserState.definitions + .getGradient('url($href)'); + colors.addAll(ref.colors); + offsets.addAll(ref.offsets); + } else { + parseStops(parserState._reader, colors, offsets); + } - final Offset center = Offset(cx, cy); - final Offset focal = - (fx != cx || fy != cy) ? Offset(fx, fy) : Offset(cx, cy); - - return Gradient.radial( - center, - r, - colors, - offsets, - spreadMethod, - transform?.storage, - focal, - 0.0, - ); - }; + double cx, cy, r, fx, fy; + if (isObjectBoundingBox) { + cx = parseDecimalOrPercentage(rawCx); + cy = parseDecimalOrPercentage(rawCy); + r = parseDecimalOrPercentage(rawR); + fx = parseDecimalOrPercentage(rawFx); + fy = parseDecimalOrPercentage(rawFy); + } else { + cx = isPercentage(rawCx) + ? parsePercentage(rawCx) * parserState.rootBounds.width + + parserState.rootBounds.left + : double.parse(rawCx); + cy = isPercentage(rawCy) + ? parsePercentage(rawCy) * parserState.rootBounds.height + + parserState.rootBounds.top + : double.parse(rawCy); + r = isPercentage(rawR) + ? parsePercentage(rawR) * + ((parserState.rootBounds.height + parserState.rootBounds.width) / + 2) + : double.parse(rawR); + fx = isPercentage(rawFx) + ? parsePercentage(rawFx) * parserState.rootBounds.width + + parserState.rootBounds.left + : double.parse(rawFx); + fy = isPercentage(rawFy) + ? parsePercentage(rawFy) * parserState.rootBounds.height + + parserState.rootBounds.top + : double.parse(rawFy); + } - parserState.definitions.addPaintServer( + parserState.definitions.addGradient( id, - shaderFunc, + DrawableRadialGradient( + center: Offset(cx, cy), + radius: r, + focal: (fx != cx || fy != cy) ? Offset(fx, fy) : Offset(cx, cy), + focalRadius: 0.0, + colors: colors, + offsets: offsets, + unitMode: isObjectBoundingBox + ? GradientUnitMode.objectBoundingBox + : GradientUnitMode.userSpaceOnUse, + spreadMethod: spreadMethod, + transform: originalTransform?.storage, + ), ); return null; } @@ -271,85 +265,65 @@ class _Elements { final List colors = []; final List offsets = []; - parseStops(parserState._reader, colors, offsets); - final Rect rootBounds = Rect.fromLTRB( - parserState.rootBounds.left, - parserState.rootBounds.top, - parserState.rootBounds.right, - parserState.rootBounds.bottom, - ); - - final PaintServer shaderFunc = (Rect bounds) { - Vector3 from, to; - Matrix4 transform = originalTransform?.clone() ?? Matrix4.identity(); - - if (isObjectBoundingBox) { - final Matrix4 scale = - affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); - final Matrix4 translate = - affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); - transform = translate.multiplied(scale)..multiply(transform); - - final Offset fromOffset = Offset( - parseDecimalOrPercentage(x1), - parseDecimalOrPercentage(y1), - ); - final Offset toOffset = Offset( - parseDecimalOrPercentage(x2), - parseDecimalOrPercentage(y2), - ); - - from = Vector3( - fromOffset.dx, - fromOffset.dy, - 0.0, - ); - to = Vector3( - toOffset.dx, - toOffset.dy, - 0.0, - ); - } else { - final Offset fromOffset = Offset( - isPercentage(x1) - ? parsePercentage(x1) * rootBounds.width + rootBounds.left - : double.parse(x1), - isPercentage(y1) - ? parsePercentage(y1) * rootBounds.height + rootBounds.top - : double.parse(y1), - ); - - final Offset toOffset = Offset( - isPercentage(x2) - ? parsePercentage(x2) * rootBounds.width + rootBounds.left - : double.parse(x2), - isPercentage(y2) - ? parsePercentage(y2) * rootBounds.height + rootBounds.top - : double.parse(y2), - ); - - from = Vector3(fromOffset.dx, fromOffset.dy, 0.0); - to = Vector3(toOffset.dx, toOffset.dy, 0.0); - } + if (parserState._reader.isEmptyElement) { + final String href = getHrefAttribute(parserState.attributes); + final DrawableLinearGradient ref = parserState.definitions + .getGradient('url($href)'); + colors.addAll(ref.colors); + offsets.addAll(ref.offsets); + } else { + parseStops(parserState._reader, colors, offsets); + } - if (transform != null) { - from = transform.transform3(from); - to = transform.transform3(to); - } + Offset fromOffset, toOffset; + if (isObjectBoundingBox) { + fromOffset = Offset( + parseDecimalOrPercentage(x1), + parseDecimalOrPercentage(y1), + ); + toOffset = Offset( + parseDecimalOrPercentage(x2), + parseDecimalOrPercentage(y2), + ); + } else { + fromOffset = Offset( + isPercentage(x1) + ? parsePercentage(x1) * parserState.rootBounds.width + + parserState.rootBounds.left + : double.parse(x1), + isPercentage(y1) + ? parsePercentage(y1) * parserState.rootBounds.height + + parserState.rootBounds.top + : double.parse(y1), + ); - return Gradient.linear( - Offset(from.x, from.y), - Offset(to.x, to.y), - colors, - offsets, - spreadMethod, + toOffset = Offset( + isPercentage(x2) + ? parsePercentage(x2) * parserState.rootBounds.width + + parserState.rootBounds.left + : double.parse(x2), + isPercentage(y2) + ? parsePercentage(y2) * parserState.rootBounds.height + + parserState.rootBounds.top + : double.parse(y2), ); - }; + } - parserState.definitions.addPaintServer( + parserState.definitions.addGradient( id, - shaderFunc, + DrawableLinearGradient( + from: fromOffset, + to: toOffset, + colors: colors, + offsets: offsets, + spreadMethod: spreadMethod, + unitMode: isObjectBoundingBox + ? GradientUnitMode.objectBoundingBox + : GradientUnitMode.userSpaceOnUse, + transform: originalTransform?.storage, + ), ); + return null; } diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index 37e3b0e73d26..c0ee2781a289 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -216,8 +216,10 @@ Future resolveImage(String href) async { // eventually this can be const, but not while we have to support // older Flutter versions -final ParagraphConstraints _infiniteParagraphConstraints = - ParagraphConstraints(width: double.infinity); // ignore: prefer_const_constructors +// ignore: prefer_const_constructors +final ParagraphConstraints _infiniteParagraphConstraints = ParagraphConstraints( + width: double.infinity, +); const DrawablePaint transparentStroke = DrawablePaint(PaintingStyle.stroke, color: Color(0x0)); Paragraph createParagraph( diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 3cbf613092e4..7a670138d840 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -149,7 +149,7 @@ double parseOpacity(List attributes) { DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri, DrawableDefinitionServer definitions, Rect bounds, {double opacity}) { - final Shader shader = definitions.getPaint(iri, bounds); + final Shader shader = definitions.getShader(iri, bounds); if (shader == null) { FlutterError.onError( FlutterErrorDetails( diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index b3f2d5b01d78..597440679e97 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -4,8 +4,10 @@ import 'dart:ui'; import 'package:meta/meta.dart'; import 'package:path_drawing/path_drawing.dart'; +import 'package:vector_math/vector_math_64.dart'; import 'render_picture.dart' as render_picture; +import 'svg/parsers.dart' show affineMatrix; typedef PaintServer = Shader Function(Rect bounds); @@ -465,7 +467,7 @@ class DrawableText implements Drawable { /// Contains reusable drawing elements that can be referenced by a String ID. class DrawableDefinitionServer { - final Map _paintServers = {}; + final Map _gradients = {}; final Map> _clipPaths = >{}; final Map _drawables = {}; @@ -488,22 +490,22 @@ class DrawableDefinitionServer { _drawables[id] = drawable; } - /// Attempt to lookup a pre-defined [Paint] by [id]. + /// Attempt to lookup a pre-defined [Shader] by [id]. /// /// [id] and [bounds] must not be null. - Shader getPaint(String id, Rect bounds) { + Shader getShader(String id, Rect bounds) { assert(id != null); assert(bounds != null); - final PaintServer srv = _paintServers[id]; + final DrawableGradient srv = _gradients[id]; + return srv != null ? srv.createShader(bounds) : null; + } - return srv != null ? srv(bounds) : null; + T getGradient(String id) { + return _gradients[id]; } - /// Add a [PaintServer] by [id]. - void addPaintServer(String id, PaintServer server) { - assert(id != null); - assert(server != null); - _paintServers[id] = server; + void addGradient(String id, DrawableGradient gradient) { + _gradients[id] = gradient; } /// Get a [List] of clip paths by [id]. @@ -518,10 +520,148 @@ class DrawableDefinitionServer { assert(paths != null); _clipPaths[id] = paths; } +} + +enum GradientUnitMode { + objectBoundingBox, + userSpaceOnUse, +} + +@immutable +abstract class DrawableGradient { + const DrawableGradient( + this.offsets, + this.colors, { + this.spreadMethod = TileMode.clamp, + this.unitMode = GradientUnitMode.objectBoundingBox, + this.transform, + }); + + final List offsets; + final List colors; + final TileMode spreadMethod; + final GradientUnitMode unitMode; + final Float64List transform; + + Shader createShader(Rect bounds); +} + +@immutable +class DrawableLinearGradient extends DrawableGradient { + const DrawableLinearGradient({ + @required this.from, + @required this.to, + @required List offsets, + @required List colors, + @required TileMode spreadMethod, + @required GradientUnitMode unitMode, + Float64List transform, + }) : super( + offsets, + colors, + spreadMethod: spreadMethod, + unitMode: unitMode, + transform: transform, + ); + + final Offset from; + final Offset to; @override - String toString() => '$runtimeType{drawables: $_drawables, ' - 'paintServers: $_paintServers, clipPaths: $_clipPaths}'; + Shader createShader(Rect bounds) { + final bool isObjectBoundingBox = + unitMode == GradientUnitMode.objectBoundingBox; + + Matrix4 m4transform = transform == null + ? Matrix4.identity() + : Matrix4.fromFloat64List(transform); + + if (isObjectBoundingBox) { + final Matrix4 scale = + affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); + final Matrix4 translate = + affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); + m4transform = translate.multiplied(scale)..multiply(m4transform); + } + + final Vector3 v3from = m4transform.transform3( + Vector3( + from.dx, + from.dy, + 0.0, + ), + ); + final Vector3 v3to = m4transform.transform3( + Vector3( + to.dx, + to.dy, + 0.0, + ), + ); + + return Gradient.linear( + Offset(v3from.x, v3from.y), + Offset(v3to.x, v3to.y), + colors, + offsets, + spreadMethod, + ); + } +} + +@immutable +class DrawableRadialGradient extends DrawableGradient { + const DrawableRadialGradient({ + @required this.center, + @required this.radius, + @required this.focal, + this.focalRadius = 0.0, + @required List offsets, + @required List colors, + @required TileMode spreadMethod, + @required GradientUnitMode unitMode, + Float64List transform, + }) : super( + offsets, + colors, + spreadMethod: spreadMethod, + unitMode: unitMode, + transform: transform, + ); + + final Offset center; + final double radius; + final Offset focal; + final double focalRadius; + + @override + Shader createShader(Rect bounds) { + final bool isObjectBoundingBox = + unitMode == GradientUnitMode.objectBoundingBox; + + Matrix4 m4transform = transform == null + ? Matrix4.identity() + : Matrix4.fromFloat64List(transform); + + if (isObjectBoundingBox) { + final Matrix4 scale = + affineMatrix(bounds.width, 0.0, 0.0, bounds.height, 0.0, 0.0); + final Matrix4 translate = + affineMatrix(1.0, 0.0, 0.0, 1.0, bounds.left, bounds.top); + m4transform = translate.multiplied(scale)..multiply(m4transform); + } + + return Gradient.radial( + center, + radius, + colors, + offsets, + spreadMethod, + m4transform.storage, + focal, + 0.0, + ); + } } /// Contains the viewport size and offset for a Drawable. From 4be9b191ec1b06d2d3016b9dd13599ba147649f1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 14 Jan 2019 01:27:57 -0800 Subject: [PATCH 210/512] add docs, remove dead code --- third_party/lib/avd.dart | 1 + third_party/lib/parser.dart | 4 + third_party/lib/src/avd/xml_parsers.dart | 2 + third_party/lib/src/avd_parser.dart | 1 + third_party/lib/src/picture_cache.dart | 1 + third_party/lib/src/picture_provider.dart | 14 ++ third_party/lib/src/picture_stream.dart | 1 + third_party/lib/src/render_picture.dart | 21 ++- third_party/lib/src/svg/colors.dart | 1 + third_party/lib/src/svg/parser_state.dart | 94 +++++++------ third_party/lib/src/svg/parsers.dart | 13 ++ third_party/lib/src/svg/xml_parsers.dart | 8 ++ third_party/lib/src/utilities/http.dart | 1 + third_party/lib/src/vector_drawable.dart | 157 ++++++++++++++++++++-- 14 files changed, 271 insertions(+), 48 deletions(-) diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index e869984082fe..92c957eab0e7 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -1,3 +1,4 @@ +// ignore_for_file: public_member_api_docs import 'dart:async'; import 'dart:convert'; import 'dart:typed_data'; diff --git a/third_party/lib/parser.dart b/third_party/lib/parser.dart index 437cf2f69b95..270e1b44be96 100644 --- a/third_party/lib/parser.dart +++ b/third_party/lib/parser.dart @@ -5,7 +5,11 @@ import 'package:xml/xml.dart' show XmlPushReader; import 'src/svg/parser_state.dart'; import 'src/vector_drawable.dart'; +/// Parses SVG data into a [DrawableRoot]. class SvgParser { + /// Parses SVG from a string to a [DrawableRoot]. + /// + /// The [key] parameter is used for debugging purposes. Future parse(String str, {String key}) async { return await SvgParserState(XmlPushReader(str), key).parse(); } diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index 38d850c14dc6..3d2b9962d2d1 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -1,3 +1,4 @@ +// ignore_for_file: public_member_api_docs import 'dart:math'; import 'dart:ui'; @@ -8,6 +9,7 @@ import 'package:xml/xml.dart'; import '../svg/colors.dart'; import '../utilities/xml.dart'; +/// The AVD namespace. const String androidNS = 'http://schemas.android.com/apk/res/android'; /// Parses an AVD @android:viewportWidth and @android:viewportHeight attributes to a [Rect]. diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index b3340d0a5fd5..7d3953dc09fe 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -1,3 +1,4 @@ +// ignore_for_file: public_member_api_docs import 'dart:ui'; import 'package:xml/xml.dart'; diff --git a/third_party/lib/src/picture_cache.dart b/third_party/lib/src/picture_cache.dart index e29d4f95c2bc..058225c42f65 100644 --- a/third_party/lib/src/picture_cache.dart +++ b/third_party/lib/src/picture_cache.dart @@ -2,6 +2,7 @@ import 'picture_stream.dart'; const int _kDefaultSize = 1000; +/// A cache for [Picture] objects. // TODO(dnfield): Implement memory based limiting, once `approximateByteCount` is exposed in engine class PictureCache { final Map _cache = diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 47464fd60ab7..e530e848f96b 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -398,6 +398,7 @@ abstract class AssetBundlePictureProvider /// const constructors so that they can be used in const expressions. const AssetBundlePictureProvider(this.decoder) : assert(decoder != null); + /// The decoder to use to turn a string into a [PictureInfo] object. final PictureInfoDecoder decoder; /// Converts a key into an [PictureStreamCompleter], and begins fetching the @@ -443,6 +444,7 @@ class NetworkPicture extends PictureProvider { const NetworkPicture(this.decoder, this.url, {this.headers, this.colorFilter}) : assert(url != null); + /// The decoder to use to turn a [Uint8List] into a [PictureInfo] object. final PictureInfoDecoder decoder; /// The URL from which the picture will be fetched. @@ -616,6 +618,18 @@ class MemoryPicture extends PictureProvider { String toString() => '$runtimeType(${describeIdentity(bytes)})'; } +/// Decodes the given [String] as a picture, associating it with the +/// given scale. +/// +/// The provided [String] should not be changed after it is provided +/// to a [StringPicture]. To provide an [PictureStream] that represents a picture +/// that changes over time, consider creating a new subclass of [PictureProvider] +/// whose [load] method returns a subclass of [PictureStreamCompleter] that can +/// handle providing multiple pictures. +/// +/// See also: +/// +/// * [SvgPicture.string] for a shorthand of an [SvgPicture] widget backed by [StringPicture]. class StringPicture extends PictureProvider { /// Creates an object that decodes a [Uint8List] buffer as a picture. /// diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart index 0fe814c15230..78d468d120a2 100644 --- a/third_party/lib/src/picture_stream.dart +++ b/third_party/lib/src/picture_stream.dart @@ -14,6 +14,7 @@ typedef ViewportCalculator = Rect Function(double devicePixelRatio); /// Represents information about a ui.Picture to be drawn on a canvas. @immutable class PictureInfo { + /// Creates a new PictureInfo object. const PictureInfo({ @required this.picture, @required this.viewport, diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index bd9c395cd746..2c7d5eb3fc3e 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -6,8 +6,10 @@ import 'package:meta/meta.dart'; import 'picture_stream.dart'; +/// A widget that displays a [dart:ui.Picture] directly. @immutable class RawPicture extends LeafRenderObjectWidget { + /// Creates a new [RawPicture] object. const RawPicture( this.picture, { Key key, @@ -15,9 +17,15 @@ class RawPicture extends LeafRenderObjectWidget { this.allowDrawingOutsideViewBox = false, }) : super(key: key); + /// The picture to paint. final PictureInfo picture; + + /// Whether this picture should match the ambient [TextDirection] or not. final bool matchTextDirection; + /// Whether to allow this picture to draw outside of its specified + /// [PictureInfo.viewport]. Caution should be used here, as this may lead to + /// greater memory usage than intended. final bool allowDrawingOutsideViewBox; @override @@ -57,6 +65,7 @@ class RawPicture extends LeafRenderObjectWidget { /// flag should be used with care, as it may result in unexpected effects or /// additional memory usage. class RenderPicture extends RenderBox { + /// Creates a new [RenderPicture]. RenderPicture({ PictureInfo picture, bool matchTextDirection = false, @@ -131,8 +140,9 @@ class RenderPicture extends RenderBox { markNeedsPaint(); } - PictureInfo _picture; + /// The information about the picture to draw. PictureInfo get picture => _picture; + PictureInfo _picture; set picture(PictureInfo val) { if (val == picture) { return; @@ -141,8 +151,13 @@ class RenderPicture extends RenderBox { markNeedsPaint(); } - bool _allowDrawingOutsideViewBox; + /// Whether to allow the rendering of this picture to exceed the + /// [PictureInfo.viewport] bounds. + /// + /// Caution should be used around setting this parameter to true, as it + /// may result in greater memory usage during rasterization. bool get allowDrawingOutsideViewBox => _allowDrawingOutsideViewBox; + bool _allowDrawingOutsideViewBox; set allowDrawingOutsideViewBox(bool val) { if (val == _allowDrawingOutsideViewBox) { return; @@ -204,6 +219,8 @@ class RenderPicture extends RenderBox { } } +/// Scales a [Canvas] to a given [viewBox] based on the [desiredSize] +/// of the widget. void scaleCanvasToViewBox( Canvas canvas, Size desiredSize, diff --git a/third_party/lib/src/svg/colors.dart b/third_party/lib/src/svg/colors.dart index c2551dfeeefb..c56582703d7b 100644 --- a/third_party/lib/src/svg/colors.dart +++ b/third_party/lib/src/svg/colors.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +/// The color black, with full opacity. const Color colorBlack = Color(0xFF000000); /// Converts a SVG Color String (either a # prefixed color string or a named color) to a [Color]. diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index e9a9d0a5100c..55c932152865 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -32,7 +32,7 @@ const Map _svgElementParsers = { 'text': _Elements.text, }; -const Map svgPathFuncs = { +const Map _svgPathFuncs = { 'circle': _Paths.circle, 'path': _Paths.path, 'rect': _Paths.rect, @@ -77,8 +77,8 @@ class _Elements { parserState._root = DrawableRoot( viewBox, [], - parserState.definitions, - parseStyle(parserState.attributes, parserState.definitions, + parserState._definitions, + parseStyle(parserState.attributes, parserState._definitions, viewBox.viewBoxRect, null), ); parserState.addGroup(parserState._root); @@ -91,13 +91,13 @@ class _Elements { [], parseStyle( parserState.attributes, - parserState.definitions, + parserState._definitions, parserState.rootBounds, parent.style, needsTransform: true, ), ); - if (!parserState.inDefs) { + if (!parserState._inDefs) { parent.children.add(group); } parserState.addGroup(group); @@ -110,7 +110,7 @@ class _Elements { [], parseStyle( parserState.attributes, - parserState.definitions, + parserState._definitions, null, parent.style, needsTransform: true, @@ -124,7 +124,7 @@ class _Elements { final String xlinkHref = getHrefAttribute(parserState.attributes); final DrawableStyle style = parseStyle( parserState.attributes, - parserState.definitions, + parserState._definitions, parserState.rootBounds, null, ); @@ -134,7 +134,7 @@ class _Elements { double.parse(parserState.attribute('y', def: '0')), ); final DrawableStyleable ref = - parserState.definitions.getDrawable('url($xlinkHref)'); + parserState._definitions.getDrawable('url($xlinkHref)'); final DrawableParent parent = parserState.currentGroup; final DrawableGroup group = DrawableGroup( [ref.mergeStyle(style)], @@ -189,7 +189,7 @@ class _Elements { if (parserState._reader.isEmptyElement) { final String href = getHrefAttribute(parserState.attributes); - final DrawableRadialGradient ref = parserState.definitions + final DrawableRadialGradient ref = parserState._definitions .getGradient('url($href)'); colors.addAll(ref.colors); offsets.addAll(ref.offsets); @@ -228,7 +228,7 @@ class _Elements { : double.parse(rawFy); } - parserState.definitions.addGradient( + parserState._definitions.addGradient( id, DrawableRadialGradient( center: Offset(cx, cy), @@ -267,7 +267,7 @@ class _Elements { final List offsets = []; if (parserState._reader.isEmptyElement) { final String href = getHrefAttribute(parserState.attributes); - final DrawableLinearGradient ref = parserState.definitions + final DrawableLinearGradient ref = parserState._definitions .getGradient('url($href)'); colors.addAll(ref.colors); offsets.addAll(ref.offsets); @@ -309,7 +309,7 @@ class _Elements { ); } - parserState.definitions.addGradient( + parserState._definitions.addGradient( id, DrawableLinearGradient( from: fromOffset, @@ -334,7 +334,7 @@ class _Elements { Path currentPath; final int depth = parserState._reader.depth; while (parserState._reader.read() && depth < parserState._reader.depth) { - final _PathFunc pathFn = svgPathFuncs[parserState._reader.name.local]; + final _PathFunc pathFn = _svgPathFuncs[parserState._reader.name.local]; if (pathFn != null) { final Path nextPath = applyTransformIfNeeded( pathFn(parserState.attributes), @@ -353,7 +353,7 @@ class _Elements { } else if (parserState._reader.name.local == 'use') { final String xlinkHref = getHrefAttribute(parserState.attributes); final DrawableStyleable definitionDrawable = - parserState.definitions.getDrawable('url($xlinkHref)'); + parserState._definitions.getDrawable('url($xlinkHref)'); void extractPathsFromDrawable(Drawable target) { if (target is DrawableShape) { @@ -371,9 +371,9 @@ class _Elements { informationCollector: (StringBuffer buff) { buff.writeln( 'The element contained an unsupported child ${parserState._reader.name.local}'); - if (parserState.key != null) { + if (parserState._key != null) { buff.writeln(); - buff.writeln('Picture key: ${parserState.key}'); + buff.writeln('Picture key: ${parserState._key}'); } }, library: 'SVG', @@ -381,7 +381,7 @@ class _Elements { )); } } - parserState.definitions.addClipPath(id, paths); + parserState._definitions.addClipPath(id, paths); return null; } @@ -453,7 +453,7 @@ class _Elements { textInfos.add(_TextInfo( parseStyle( parserState.attributes, - parserState.definitions, + parserState._definitions, parserState.rootBounds, lastTextInfo?.style ?? parserState.currentGroup.style, needsTransform: true, @@ -553,16 +553,21 @@ class _SvgGroupTuple { final DrawableParent drawable; } +/// The implementation of [SvgParser]. +/// +/// Maintains state while pushing an [XmlPushReader] through the SVG tree. class SvgParserState { - SvgParserState(this._reader, this.key) : assert(_reader != null); + /// Creates a new [SvgParserState]. + SvgParserState(this._reader, this._key) : assert(_reader != null); final XmlPushReader _reader; - final String key; - final DrawableDefinitionServer definitions = DrawableDefinitionServer(); - final Queue<_SvgGroupTuple> parentDrawables = ListQueue<_SvgGroupTuple>(10); + final String _key; + final DrawableDefinitionServer _definitions = DrawableDefinitionServer(); + final Queue<_SvgGroupTuple> _parentDrawables = ListQueue<_SvgGroupTuple>(10); DrawableRoot _root; - bool inDefs = false; + bool _inDefs = false; + /// Drive the [XmlTextReader] to EOF and produce a [DrawableRoot]. Future parse() async { while (_reader.read()) { switch (_reader.nodeType) { @@ -595,81 +600,94 @@ class SvgParserState { return _root; } + /// The XML Attributes of the current node in the tree. List get attributes => _reader.attributes; + /// Gets the attribute for the current position of the parser. String attribute(String name, {String def, String namespace}) => getAttribute(attributes, name, def: def, namespace: namespace); + /// The current group, if any, in the [Drawable] heirarchy. DrawableParent get currentGroup { - assert(parentDrawables != null); - assert(parentDrawables.isNotEmpty); - return parentDrawables.last.drawable; + assert(_parentDrawables != null); + assert(_parentDrawables.isNotEmpty); + return _parentDrawables.last.drawable; } + /// The root bounds of the drawable. Rect get rootBounds { assert(_root != null, 'Cannot get rootBounds with null root'); assert(_root.viewport != null); return _root.viewport.viewBoxRect; } + /// Whether this [DrawableStyleable] belongs in the [DrawableDefinitions] or not. bool checkForIri(DrawableStyleable drawable) { final String iri = buildUrlIri(attributes); if (iri != emptyUrlIri) { - definitions.addDrawable(iri, drawable); + _definitions.addDrawable(iri, drawable); return true; } return false; } + /// Appends a group to the collection. void addGroup(DrawableParent drawable) { - parentDrawables.addLast(_SvgGroupTuple(_reader.name.local, drawable)); + _parentDrawables.addLast(_SvgGroupTuple(_reader.name.local, drawable)); checkForIri(drawable); } + /// Appends a [DrawableShape] to the [currentGroup]. bool addShape() { - final _PathFunc pathFunc = svgPathFuncs[_reader.name.local]; + final _PathFunc pathFunc = _svgPathFuncs[_reader.name.local]; if (pathFunc == null) { return false; } - final DrawableParent parent = parentDrawables.last.drawable; + final DrawableParent parent = _parentDrawables.last.drawable; final DrawableStyle parentStyle = parent.style; final Path path = pathFunc(attributes); final DrawableStyleable drawable = DrawableShape( path, parseStyle( attributes, - definitions, + _definitions, path.getBounds(), parentStyle, ), transform: parseTransform(getAttribute(attributes, 'transform'))?.storage, ); final bool isIri = checkForIri(drawable); - if (!inDefs || !isIri) { + if (!_inDefs || !isIri) { parent.children.add(drawable); } return true; } + /// Potentially handles a starting element. bool startElement() { if (_reader.name.local == 'defs') { // we won't get a call to `endElement()` if we're in a '' - inDefs = !_reader.isEmptyElement; + _inDefs = !_reader.isEmptyElement; return true; } return addShape(); } + /// Handles the end of an XML element. void endElement() { - if (_reader.name.local == parentDrawables.last.name) { - parentDrawables.removeLast(); + if (_reader.name.local == _parentDrawables.last.name) { + _parentDrawables.removeLast(); } if (_reader.name.local == 'defs') { - inDefs = false; + _inDefs = false; } } + /// Prints an error for unhandled elements. + /// + /// Will only print an error once for unhandled/unexpected elements, except for + /// ` + + + + + + + + + + + + +'''; + final SvgParser parser = SvgParser(); + expect( + parser.parse(svgStr, warningsAsErrors: true), + throwsA(anything), + ); + }); + + test('Warns about unsupported elements by default', () async { + const String svgStr = ''' + + + svg/stick_figure + Created with Sketch. + + + + + + + + + + + + + +'''; + + final SvgParser parser = SvgParser(); + expect(await parser.parse(svgStr), isA()); + }); } From b72bc02718d3c1f2db7fa7488e3102f9989d651e Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Fri, 22 Jan 2021 09:40:39 -0800 Subject: [PATCH 375/512] Remove return stmts from Future.catchError (#477) * Remove return stmt from Future.catchError * Remove one more return statement * Replace empty return for control flow --- third_party/lib/src/picture_provider.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 11a057d06cb1..7aaa6f9dfcc0 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -340,7 +340,7 @@ abstract class PictureProvider { ).catchError((Object exception, StackTrace stack) async { if (onError != null) { onError(exception, stack); - return Future.error(exception, stack); + return; } FlutterError.reportError(FlutterErrorDetails( exception: exception, @@ -354,7 +354,6 @@ abstract class PictureProvider { yield DiagnosticsProperty('Picture key', obtainedKey, defaultValue: null); })); - return null; }); return stream; } From b629bc1ca9082aa545fe69660efce3fe452ea6b2 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Feb 2021 15:56:14 -0800 Subject: [PATCH 376/512] recreate example project --- third_party/example/android/.gitignore | 7 +- third_party/example/android/app/build.gradle | 12 +- .../android/app/src/main/AndroidManifest.xml | 35 ++- .../com/example/example/MainActivity.kt | 8 +- .../res/drawable-v21/launch_background.xml | 12 + .../app/src/main/res/values-night/styles.xml | 18 ++ .../app/src/main/res/values/styles.xml | 12 +- third_party/example/android/build.gradle | 2 +- .../example/android/example_android.iml | 2 +- third_party/example/android/gradle.properties | 1 - .../gradle/wrapper/gradle-wrapper.properties | 2 +- third_party/example/android/settings.gradle | 18 +- .../xcshareddata/WorkspaceSettings.xcsettings | 8 + third_party/example/linux/.gitignore | 1 + third_party/example/linux/CMakeLists.txt | 106 ++++++++ .../example/linux/flutter/CMakeLists.txt | 91 +++++++ .../flutter/generated_plugin_registrant.cc | 9 + .../flutter/generated_plugin_registrant.h | 13 + .../linux/flutter/generated_plugins.cmake | 15 ++ third_party/example/linux/main.cc | 6 + third_party/example/linux/my_application.cc | 105 ++++++++ third_party/example/linux/my_application.h | 18 ++ third_party/example/pubspec.yaml | 8 - third_party/example/windows/.gitignore | 17 ++ third_party/example/windows/CMakeLists.txt | 95 +++++++ .../example/windows/flutter/CMakeLists.txt | 103 ++++++++ .../flutter/generated_plugin_registrant.cc | 9 + .../flutter/generated_plugin_registrant.h | 13 + .../windows/flutter/generated_plugins.cmake | 15 ++ .../example/windows/runner/CMakeLists.txt | 18 ++ third_party/example/windows/runner/Runner.rc | 121 +++++++++ .../example/windows/runner/flutter_window.cpp | 64 +++++ .../example/windows/runner/flutter_window.h | 39 +++ third_party/example/windows/runner/main.cpp | 42 +++ third_party/example/windows/runner/resource.h | 16 ++ .../windows/runner/resources/app_icon.ico | Bin 0 -> 33772 bytes .../example/windows/runner/run_loop.cpp | 66 +++++ third_party/example/windows/runner/run_loop.h | 40 +++ .../windows/runner/runner.exe.manifest | 20 ++ third_party/example/windows/runner/utils.cpp | 64 +++++ third_party/example/windows/runner/utils.h | 19 ++ .../example/windows/runner/win32_window.cpp | 245 ++++++++++++++++++ .../example/windows/runner/win32_window.h | 98 +++++++ 43 files changed, 1556 insertions(+), 57 deletions(-) create mode 100644 third_party/example/android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 third_party/example/android/app/src/main/res/values-night/styles.xml create mode 100644 third_party/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 third_party/example/linux/.gitignore create mode 100644 third_party/example/linux/CMakeLists.txt create mode 100644 third_party/example/linux/flutter/CMakeLists.txt create mode 100644 third_party/example/linux/flutter/generated_plugin_registrant.cc create mode 100644 third_party/example/linux/flutter/generated_plugin_registrant.h create mode 100644 third_party/example/linux/flutter/generated_plugins.cmake create mode 100644 third_party/example/linux/main.cc create mode 100644 third_party/example/linux/my_application.cc create mode 100644 third_party/example/linux/my_application.h create mode 100644 third_party/example/windows/.gitignore create mode 100644 third_party/example/windows/CMakeLists.txt create mode 100644 third_party/example/windows/flutter/CMakeLists.txt create mode 100644 third_party/example/windows/flutter/generated_plugin_registrant.cc create mode 100644 third_party/example/windows/flutter/generated_plugin_registrant.h create mode 100644 third_party/example/windows/flutter/generated_plugins.cmake create mode 100644 third_party/example/windows/runner/CMakeLists.txt create mode 100644 third_party/example/windows/runner/Runner.rc create mode 100644 third_party/example/windows/runner/flutter_window.cpp create mode 100644 third_party/example/windows/runner/flutter_window.h create mode 100644 third_party/example/windows/runner/main.cpp create mode 100644 third_party/example/windows/runner/resource.h create mode 100644 third_party/example/windows/runner/resources/app_icon.ico create mode 100644 third_party/example/windows/runner/run_loop.cpp create mode 100644 third_party/example/windows/runner/run_loop.h create mode 100644 third_party/example/windows/runner/runner.exe.manifest create mode 100644 third_party/example/windows/runner/utils.cpp create mode 100644 third_party/example/windows/runner/utils.h create mode 100644 third_party/example/windows/runner/win32_window.cpp create mode 100644 third_party/example/windows/runner/win32_window.h diff --git a/third_party/example/android/.gitignore b/third_party/example/android/.gitignore index 704324be15c2..0a741cb43d66 100644 --- a/third_party/example/android/.gitignore +++ b/third_party/example/android/.gitignore @@ -4,7 +4,8 @@ gradle-wrapper.jar /gradlew /gradlew.bat /local.properties -.DS_Store -/build -.idea GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties diff --git a/third_party/example/android/app/build.gradle b/third_party/example/android/app/build.gradle index 0f6a5e54bab2..6ca23448e5d8 100644 --- a/third_party/example/android/app/build.gradle +++ b/third_party/example/android/app/build.gradle @@ -26,24 +26,19 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion 30 sourceSets { main.java.srcDirs += 'src/main/kotlin' } - lintOptions { - disable 'InvalidPackage' - } - defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.example" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -61,7 +56,4 @@ flutter { dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' } diff --git a/third_party/example/android/app/src/main/AndroidManifest.xml b/third_party/example/android/app/src/main/AndroidManifest.xml index 7e6679c3d20d..34dd77efb2ef 100644 --- a/third_party/example/android/app/src/main/AndroidManifest.xml +++ b/third_party/example/android/app/src/main/AndroidManifest.xml @@ -1,12 +1,6 @@ - - - + + android:name="io.flutter.embedding.android.NormalTheme" + android:resource="@style/NormalTheme" + /> + + + + diff --git a/third_party/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/third_party/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt index 777dcaeb6d7b..e793a000d6a9 100644 --- a/third_party/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt +++ b/third_party/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt @@ -1,12 +1,6 @@ package com.example.example -import android.os.Bundle -import io.flutter.app.FlutterActivity -import io.flutter.plugins.GeneratedPluginRegistrant +import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - GeneratedPluginRegistrant.registerWith(this) - } } diff --git a/third_party/example/android/app/src/main/res/drawable-v21/launch_background.xml b/third_party/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 000000000000..f74085f3f6a2 --- /dev/null +++ b/third_party/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/third_party/example/android/app/src/main/res/values-night/styles.xml b/third_party/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 000000000000..449a9f930826 --- /dev/null +++ b/third_party/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/third_party/example/android/app/src/main/res/values/styles.xml b/third_party/example/android/app/src/main/res/values/styles.xml index 00fa4417cfbe..d74aa35c2826 100644 --- a/third_party/example/android/app/src/main/res/values/styles.xml +++ b/third_party/example/android/app/src/main/res/values/styles.xml @@ -1,8 +1,18 @@ - + + diff --git a/third_party/example/android/build.gradle b/third_party/example/android/build.gradle index 3100ad2d5553..c505a8635265 100644 --- a/third_party/example/android/build.gradle +++ b/third_party/example/android/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:4.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/third_party/example/android/example_android.iml b/third_party/example/android/example_android.iml index 1029d721f479..18999696a6a3 100644 --- a/third_party/example/android/example_android.iml +++ b/third_party/example/android/example_android.iml @@ -21,7 +21,7 @@ - + diff --git a/third_party/example/android/gradle.properties b/third_party/example/android/gradle.properties index 38c8d4544ff1..94adc3a3f97a 100644 --- a/third_party/example/android/gradle.properties +++ b/third_party/example/android/gradle.properties @@ -1,4 +1,3 @@ org.gradle.jvmargs=-Xmx1536M -android.enableR8=true android.useAndroidX=true android.enableJetifier=true diff --git a/third_party/example/android/gradle/wrapper/gradle-wrapper.properties b/third_party/example/android/gradle/wrapper/gradle-wrapper.properties index 296b146b7318..bc6a58afdda2 100644 --- a/third_party/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/third_party/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/third_party/example/android/settings.gradle b/third_party/example/android/settings.gradle index 5a2f14fb18f6..44e62bcf06ae 100644 --- a/third_party/example/android/settings.gradle +++ b/third_party/example/android/settings.gradle @@ -1,15 +1,11 @@ include ':app' -def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() +def localPropertiesFile = new File(rootProject.projectDir, "local.properties") +def properties = new Properties() -def plugins = new Properties() -def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') -if (pluginsFile.exists()) { - pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } -} +assert localPropertiesFile.exists() +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } -plugins.each { name, path -> - def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() - include ":$name" - project(":$name").projectDir = pluginDirectory -} +def flutterSdkPath = properties.getProperty("flutter.sdk") +assert flutterSdkPath != null, "flutter.sdk not set in local.properties" +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" diff --git a/third_party/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/third_party/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 000000000000..f9b0d7c5ea15 --- /dev/null +++ b/third_party/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/third_party/example/linux/.gitignore b/third_party/example/linux/.gitignore new file mode 100644 index 000000000000..d3896c98444f --- /dev/null +++ b/third_party/example/linux/.gitignore @@ -0,0 +1 @@ +flutter/ephemeral diff --git a/third_party/example/linux/CMakeLists.txt b/third_party/example/linux/CMakeLists.txt new file mode 100644 index 000000000000..290c3e841e82 --- /dev/null +++ b/third_party/example/linux/CMakeLists.txt @@ -0,0 +1,106 @@ +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +set(BINARY_NAME "example") +set(APPLICATION_ID "com.example.example") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_14) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) + +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") + +# Application build +add_executable(${BINARY_NAME} + "main.cc" + "my_application.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) +apply_standard_settings(${BINARY_NAME}) +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) +add_dependencies(${BINARY_NAME} flutter_assemble) +# Only the install-generated bundle's copy of the executable will launch +# correctly, since the resources must in the right relative locations. To avoid +# people trying to run the unbundled copy, put it in a subdirectory instead of +# the default top-level location. +set_target_properties(${BINARY_NAME} + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" +) + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/third_party/example/linux/flutter/CMakeLists.txt b/third_party/example/linux/flutter/CMakeLists.txt new file mode 100644 index 000000000000..a1da1b9e5320 --- /dev/null +++ b/third_party/example/linux/flutter/CMakeLists.txt @@ -0,0 +1,91 @@ +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +find_package(PkgConfig REQUIRED) +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) +pkg_check_modules(BLKID REQUIRED IMPORTED_TARGET blkid) +pkg_check_modules(LZMA REQUIRED IMPORTED_TARGET liblzma) + +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "fl_basic_message_channel.h" + "fl_binary_codec.h" + "fl_binary_messenger.h" + "fl_dart_project.h" + "fl_engine.h" + "fl_json_message_codec.h" + "fl_json_method_codec.h" + "fl_message_codec.h" + "fl_method_call.h" + "fl_method_channel.h" + "fl_method_codec.h" + "fl_method_response.h" + "fl_plugin_registrar.h" + "fl_plugin_registry.h" + "fl_standard_message_codec.h" + "fl_standard_method_codec.h" + "fl_string_codec.h" + "fl_value.h" + "fl_view.h" + "flutter_linux.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE + PkgConfig::GTK + PkgConfig::GLIB + PkgConfig::GIO + PkgConfig::BLKID + PkgConfig::LZMA +) +add_dependencies(flutter flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CMAKE_CURRENT_BINARY_DIR}/_phony_ + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" + linux-x64 ${CMAKE_BUILD_TYPE} + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} +) diff --git a/third_party/example/linux/flutter/generated_plugin_registrant.cc b/third_party/example/linux/flutter/generated_plugin_registrant.cc new file mode 100644 index 000000000000..d38195aa0412 --- /dev/null +++ b/third_party/example/linux/flutter/generated_plugin_registrant.cc @@ -0,0 +1,9 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + + +void fl_register_plugins(FlPluginRegistry* registry) { +} diff --git a/third_party/example/linux/flutter/generated_plugin_registrant.h b/third_party/example/linux/flutter/generated_plugin_registrant.h new file mode 100644 index 000000000000..9bf7478940c1 --- /dev/null +++ b/third_party/example/linux/flutter/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void fl_register_plugins(FlPluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/third_party/example/linux/flutter/generated_plugins.cmake b/third_party/example/linux/flutter/generated_plugins.cmake new file mode 100644 index 000000000000..51436ae8c982 --- /dev/null +++ b/third_party/example/linux/flutter/generated_plugins.cmake @@ -0,0 +1,15 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) diff --git a/third_party/example/linux/main.cc b/third_party/example/linux/main.cc new file mode 100644 index 000000000000..e7c5c5437037 --- /dev/null +++ b/third_party/example/linux/main.cc @@ -0,0 +1,6 @@ +#include "my_application.h" + +int main(int argc, char** argv) { + g_autoptr(MyApplication) app = my_application_new(); + return g_application_run(G_APPLICATION(app), argc, argv); +} diff --git a/third_party/example/linux/my_application.cc b/third_party/example/linux/my_application.cc new file mode 100644 index 000000000000..634f4c519339 --- /dev/null +++ b/third_party/example/linux/my_application.cc @@ -0,0 +1,105 @@ +#include "my_application.h" + +#include +#ifdef GDK_WINDOWING_X11 +#include +#endif + +#include "flutter/generated_plugin_registrant.h" + +struct _MyApplication { + GtkApplication parent_instance; + char** dart_entrypoint_arguments; +}; + +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) + +// Implements GApplication::activate. +static void my_application_activate(GApplication* application) { + MyApplication* self = MY_APPLICATION(application); + GtkWindow* window = + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); + + // Use a header bar when running in GNOME as this is the common style used + // by applications and is the setup most users will be using (e.g. Ubuntu + // desktop). + // If running on X and not using GNOME then just use a traditional title bar + // in case the window manager does more exotic layout, e.g. tiling. + // If running on Wayland assume the header bar will work (may need changing + // if future cases occur). + gboolean use_header_bar = TRUE; +#ifdef GDK_WINDOWING_X11 + GdkScreen *screen = gtk_window_get_screen(window); + if (GDK_IS_X11_SCREEN(screen)) { + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); + if (g_strcmp0(wm_name, "GNOME Shell") != 0) { + use_header_bar = FALSE; + } + } +#endif + if (use_header_bar) { + GtkHeaderBar *header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); + gtk_widget_show(GTK_WIDGET(header_bar)); + gtk_header_bar_set_title(header_bar, "example"); + gtk_header_bar_set_show_close_button(header_bar, TRUE); + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); + } + else { + gtk_window_set_title(window, "example"); + } + + gtk_window_set_default_size(window, 1280, 720); + gtk_widget_show(GTK_WIDGET(window)); + + g_autoptr(FlDartProject) project = fl_dart_project_new(); + fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); + + FlView* view = fl_view_new(project); + gtk_widget_show(GTK_WIDGET(view)); + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); + + fl_register_plugins(FL_PLUGIN_REGISTRY(view)); + + gtk_widget_grab_focus(GTK_WIDGET(view)); +} + +// Implements GApplication::local_command_line. +static gboolean my_application_local_command_line(GApplication* application, gchar ***arguments, int *exit_status) { + MyApplication* self = MY_APPLICATION(application); + // Strip out the first argument as it is the binary name. + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); + + g_autoptr(GError) error = nullptr; + if (!g_application_register(application, nullptr, &error)) { + g_warning("Failed to register: %s", error->message); + *exit_status = 1; + return TRUE; + } + + g_application_activate(application); + *exit_status = 0; + + return TRUE; +} + +// Implements GObject::dispose. +static void my_application_dispose(GObject *object) { + MyApplication* self = MY_APPLICATION(object); + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); + G_OBJECT_CLASS(my_application_parent_class)->dispose(object); +} + +static void my_application_class_init(MyApplicationClass* klass) { + G_APPLICATION_CLASS(klass)->activate = my_application_activate; + G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; + G_OBJECT_CLASS(klass)->dispose = my_application_dispose; +} + +static void my_application_init(MyApplication* self) {} + +MyApplication* my_application_new() { + return MY_APPLICATION(g_object_new(my_application_get_type(), + "application-id", APPLICATION_ID, + "flags", G_APPLICATION_NON_UNIQUE, + nullptr)); +} diff --git a/third_party/example/linux/my_application.h b/third_party/example/linux/my_application.h new file mode 100644 index 000000000000..72271d5e4170 --- /dev/null +++ b/third_party/example/linux/my_application.h @@ -0,0 +1,18 @@ +#ifndef FLUTTER_MY_APPLICATION_H_ +#define FLUTTER_MY_APPLICATION_H_ + +#include + +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, + GtkApplication) + +/** + * my_application_new: + * + * Creates a new Flutter-based application. + * + * Returns: a new #MyApplication. + */ +MyApplication* my_application_new(); + +#endif // FLUTTER_MY_APPLICATION_H_ diff --git a/third_party/example/pubspec.yaml b/third_party/example/pubspec.yaml index 24b6d571c7bb..c93f4bba8454 100644 --- a/third_party/example/pubspec.yaml +++ b/third_party/example/pubspec.yaml @@ -9,18 +9,10 @@ dependencies: flutter_svg: path: ../ -# For information on the generic Dart part of this file, see the -# following page: https://www.dartlang.org/tools/pub/pubspec - # The following section is specific to Flutter. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - # To add assets to your application, add an assets section, like this: assets: - assets/ - assets/w3samples/ diff --git a/third_party/example/windows/.gitignore b/third_party/example/windows/.gitignore new file mode 100644 index 000000000000..d492d0d98c8f --- /dev/null +++ b/third_party/example/windows/.gitignore @@ -0,0 +1,17 @@ +flutter/ephemeral/ + +# Visual Studio user-specific files. +*.suo +*.user +*.userosscache +*.sln.docstates + +# Visual Studio build-related files. +x64/ +x86/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ diff --git a/third_party/example/windows/CMakeLists.txt b/third_party/example/windows/CMakeLists.txt new file mode 100644 index 000000000000..abf90408efb4 --- /dev/null +++ b/third_party/example/windows/CMakeLists.txt @@ -0,0 +1,95 @@ +cmake_minimum_required(VERSION 3.15) +project(example LANGUAGES CXX) + +set(BINARY_NAME "example") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") + endif() +endif() + +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build +add_subdirectory("runner") + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/third_party/example/windows/flutter/CMakeLists.txt b/third_party/example/windows/flutter/CMakeLists.txt new file mode 100644 index 000000000000..b02c5485c957 --- /dev/null +++ b/third_party/example/windows/flutter/CMakeLists.txt @@ -0,0 +1,103 @@ +cmake_minimum_required(VERSION 3.15) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +# TODO: Move the rest of this into files in ephemeral. See +# https://github.com/flutter/flutter/issues/57146. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) +set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" + "flutter_texture_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +# === Flutter tool backend === +# _phony_ is a non-existent file to force this command to run every time, +# since currently there's no way to get a full input/output list from the +# flutter tool. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/third_party/example/windows/flutter/generated_plugin_registrant.cc b/third_party/example/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 000000000000..4bfa0f3a3a75 --- /dev/null +++ b/third_party/example/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,9 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + + +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/third_party/example/windows/flutter/generated_plugin_registrant.h b/third_party/example/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 000000000000..9846246b4dac --- /dev/null +++ b/third_party/example/windows/flutter/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/third_party/example/windows/flutter/generated_plugins.cmake b/third_party/example/windows/flutter/generated_plugins.cmake new file mode 100644 index 000000000000..4d10c2518654 --- /dev/null +++ b/third_party/example/windows/flutter/generated_plugins.cmake @@ -0,0 +1,15 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) + list(APPEND PLUGIN_BUNDLED_LIBRARIES $) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) +endforeach(plugin) diff --git a/third_party/example/windows/runner/CMakeLists.txt b/third_party/example/windows/runner/CMakeLists.txt new file mode 100644 index 000000000000..977e38b5d1d2 --- /dev/null +++ b/third_party/example/windows/runner/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.15) +project(runner LANGUAGES CXX) + +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "run_loop.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) +apply_standard_settings(${BINARY_NAME}) +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/third_party/example/windows/runner/Runner.rc b/third_party/example/windows/runner/Runner.rc new file mode 100644 index 000000000000..51812dcd4878 --- /dev/null +++ b/third_party/example/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#ifdef FLUTTER_BUILD_NUMBER +#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER +#else +#define VERSION_AS_NUMBER 1,0,0 +#endif + +#ifdef FLUTTER_BUILD_NAME +#define VERSION_AS_STRING #FLUTTER_BUILD_NAME +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "A new Flutter project." "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "example" "\0" + VALUE "LegalCopyright", "Copyright (C) 2021 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "example.exe" "\0" + VALUE "ProductName", "example" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/third_party/example/windows/runner/flutter_window.cpp b/third_party/example/windows/runner/flutter_window.cpp new file mode 100644 index 000000000000..c422723045ca --- /dev/null +++ b/third_party/example/windows/runner/flutter_window.cpp @@ -0,0 +1,64 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(RunLoop* run_loop, + const flutter::DartProject& project) + : run_loop_(run_loop), project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + run_loop_->RegisterFlutterInstance(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + run_loop_->UnregisterFlutterInstance(flutter_controller_->engine()); + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opporutunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/third_party/example/windows/runner/flutter_window.h b/third_party/example/windows/runner/flutter_window.h new file mode 100644 index 000000000000..b663ddd50125 --- /dev/null +++ b/third_party/example/windows/runner/flutter_window.h @@ -0,0 +1,39 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "run_loop.h" +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow driven by the |run_loop|, hosting a + // Flutter view running |project|. + explicit FlutterWindow(RunLoop* run_loop, + const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The run loop driving events for this window. + RunLoop* run_loop_; + + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/third_party/example/windows/runner/main.cpp b/third_party/example/windows/runner/main.cpp new file mode 100644 index 000000000000..b637809bd386 --- /dev/null +++ b/third_party/example/windows/runner/main.cpp @@ -0,0 +1,42 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "run_loop.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + RunLoop run_loop; + + flutter::DartProject project(L"data"); + + std::vector command_line_arguments = + GetCommandLineArguments(); + + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + FlutterWindow window(&run_loop, project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.CreateAndShow(L"example", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + run_loop.Run(); + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/third_party/example/windows/runner/resource.h b/third_party/example/windows/runner/resource.h new file mode 100644 index 000000000000..66a65d1e4a79 --- /dev/null +++ b/third_party/example/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/third_party/example/windows/runner/resources/app_icon.ico b/third_party/example/windows/runner/resources/app_icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c04e20caf6370ebb9253ad831cc31de4a9c965f6 GIT binary patch literal 33772 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 literal 0 HcmV?d00001 diff --git a/third_party/example/windows/runner/run_loop.cpp b/third_party/example/windows/runner/run_loop.cpp new file mode 100644 index 000000000000..2d6636ab6bc6 --- /dev/null +++ b/third_party/example/windows/runner/run_loop.cpp @@ -0,0 +1,66 @@ +#include "run_loop.h" + +#include + +#include + +RunLoop::RunLoop() {} + +RunLoop::~RunLoop() {} + +void RunLoop::Run() { + bool keep_running = true; + TimePoint next_flutter_event_time = TimePoint::clock::now(); + while (keep_running) { + std::chrono::nanoseconds wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - TimePoint::clock::now()); + ::MsgWaitForMultipleObjects( + 0, nullptr, FALSE, static_cast(wait_duration.count() / 1000), + QS_ALLINPUT); + bool processed_events = false; + MSG message; + // All pending Windows messages must be processed; MsgWaitForMultipleObjects + // won't return again for items left in the queue after PeekMessage. + while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { + processed_events = true; + if (message.message == WM_QUIT) { + keep_running = false; + break; + } + ::TranslateMessage(&message); + ::DispatchMessage(&message); + // Allow Flutter to process messages each time a Windows message is + // processed, to prevent starvation. + next_flutter_event_time = + std::min(next_flutter_event_time, ProcessFlutterMessages()); + } + // If the PeekMessage loop didn't run, process Flutter messages. + if (!processed_events) { + next_flutter_event_time = + std::min(next_flutter_event_time, ProcessFlutterMessages()); + } + } +} + +void RunLoop::RegisterFlutterInstance( + flutter::FlutterEngine* flutter_instance) { + flutter_instances_.insert(flutter_instance); +} + +void RunLoop::UnregisterFlutterInstance( + flutter::FlutterEngine* flutter_instance) { + flutter_instances_.erase(flutter_instance); +} + +RunLoop::TimePoint RunLoop::ProcessFlutterMessages() { + TimePoint next_event_time = TimePoint::max(); + for (auto instance : flutter_instances_) { + std::chrono::nanoseconds wait_duration = instance->ProcessMessages(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, TimePoint::clock::now() + wait_duration); + } + } + return next_event_time; +} diff --git a/third_party/example/windows/runner/run_loop.h b/third_party/example/windows/runner/run_loop.h new file mode 100644 index 000000000000..000d3624638e --- /dev/null +++ b/third_party/example/windows/runner/run_loop.h @@ -0,0 +1,40 @@ +#ifndef RUNNER_RUN_LOOP_H_ +#define RUNNER_RUN_LOOP_H_ + +#include + +#include +#include + +// A runloop that will service events for Flutter instances as well +// as native messages. +class RunLoop { + public: + RunLoop(); + ~RunLoop(); + + // Prevent copying + RunLoop(RunLoop const&) = delete; + RunLoop& operator=(RunLoop const&) = delete; + + // Runs the run loop until the application quits. + void Run(); + + // Registers the given Flutter instance for event servicing. + void RegisterFlutterInstance( + flutter::FlutterEngine* flutter_instance); + + // Unregisters the given Flutter instance from event servicing. + void UnregisterFlutterInstance( + flutter::FlutterEngine* flutter_instance); + + private: + using TimePoint = std::chrono::steady_clock::time_point; + + // Processes all currently pending messages for registered Flutter instances. + TimePoint ProcessFlutterMessages(); + + std::set flutter_instances_; +}; + +#endif // RUNNER_RUN_LOOP_H_ diff --git a/third_party/example/windows/runner/runner.exe.manifest b/third_party/example/windows/runner/runner.exe.manifest new file mode 100644 index 000000000000..c977c4a42589 --- /dev/null +++ b/third_party/example/windows/runner/runner.exe.manifest @@ -0,0 +1,20 @@ + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/third_party/example/windows/runner/utils.cpp b/third_party/example/windows/runner/utils.cpp new file mode 100644 index 000000000000..d19bdbbcc322 --- /dev/null +++ b/third_party/example/windows/runner/utils.cpp @@ -0,0 +1,64 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} + +std::vector GetCommandLineArguments() { + // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. + int argc; + wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); + if (argv == nullptr) { + return std::vector(); + } + + std::vector command_line_arguments; + + // Skip the first argument as it's the binary name. + for (int i = 1; i < argc; i++) { + command_line_arguments.push_back(Utf8FromUtf16(argv[i])); + } + + ::LocalFree(argv); + + return command_line_arguments; +} + +std::string Utf8FromUtf16(const wchar_t* utf16_string) { + if (utf16_string == nullptr) { + return std::string(); + } + int target_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, nullptr, 0, nullptr, nullptr); + if (target_length == 0) { + return std::string(); + } + std::string utf8_string; + utf8_string.resize(target_length); + int converted_length = ::WideCharToMultiByte( + CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, + -1, utf8_string.data(), + target_length, nullptr, nullptr); + if (converted_length == 0) { + return std::string(); + } + return utf8_string; +} diff --git a/third_party/example/windows/runner/utils.h b/third_party/example/windows/runner/utils.h new file mode 100644 index 000000000000..3879d5475579 --- /dev/null +++ b/third_party/example/windows/runner/utils.h @@ -0,0 +1,19 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +#include +#include + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string +// encoded in UTF-8. Returns an empty std::string on failure. +std::string Utf8FromUtf16(const wchar_t* utf16_string); + +// Gets the command line arguments passed in as a std::vector, +// encoded in UTF-8. Returns an empty std::vector on failure. +std::vector GetCommandLineArguments(); + +#endif // RUNNER_UTILS_H_ diff --git a/third_party/example/windows/runner/win32_window.cpp b/third_party/example/windows/runner/win32_window.cpp new file mode 100644 index 000000000000..c10f08dc7da6 --- /dev/null +++ b/third_party/example/windows/runner/win32_window.cpp @@ -0,0 +1,245 @@ +#include "win32_window.h" + +#include + +#include "resource.h" + +namespace { + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + FreeLibrary(user32_module); + } +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + return OnCreate(); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: { + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + } + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} diff --git a/third_party/example/windows/runner/win32_window.h b/third_party/example/windows/runner/win32_window.h new file mode 100644 index 000000000000..17ba431125b4 --- /dev/null +++ b/third_party/example/windows/runner/win32_window.h @@ -0,0 +1,98 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates and shows a win32 window with |title| and position and size using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size to will treat the width height passed in to this function + // as logical pixels and scale to appropriate for the default monitor. Returns + // true if the window was created successfully. + bool CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responsponds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ From ed0a6b4eac02200cc11c4621e6c17a9b869fd62e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 22 Feb 2021 10:29:03 -0800 Subject: [PATCH 377/512] put key into errors (#497) --- third_party/lib/src/svg/parser_state.dart | 16 ++++++++-- third_party/lib/src/svg/xml_parsers.dart | 38 +++++++++++++++++------ third_party/lib/src/utilities/errors.dart | 4 +-- third_party/test/error_test.dart | 31 ++++++++++++++++++ 4 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 third_party/test/error_test.dart diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index 459394171cc7..42cfa96f696e 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -106,6 +106,7 @@ class _Elements { id, [], parseStyle( + parserState._key, parserState.attributes, parserState._definitions, viewBox!.viewBoxRect, @@ -122,6 +123,7 @@ class _Elements { [], parserState._definitions, parseStyle( + parserState._key, parserState.attributes, parserState._definitions, viewBox.viewBoxRect, @@ -138,6 +140,7 @@ class _Elements { parserState.attribute('id', def: ''), [], parseStyle( + parserState._key, parserState.attributes, parserState._definitions, parserState.rootBounds, @@ -159,6 +162,7 @@ class _Elements { parserState.attribute('id', def: ''), [], parseStyle( + parserState._key, parserState.attributes, parserState._definitions, null, @@ -178,6 +182,7 @@ class _Elements { } final DrawableStyle style = parseStyle( + parserState._key, parserState.attributes, parserState._definitions, parserState.rootBounds, @@ -240,7 +245,9 @@ class _Elements { } static Future? radialGradient( - SvgParserState parserState, bool warningsAsErrors) { + SvgParserState parserState, + bool warningsAsErrors, + ) { final String? gradientUnits = getAttribute( parserState.attributes, 'gradientUnits', @@ -267,7 +274,7 @@ class _Elements { final DrawableGradient? ref = parserState._definitions.getGradient('url($href)'); if (ref == null) { - reportMissingDef(href, 'radialGradient'); + reportMissingDef(parserState._key, href, 'radialGradient'); } else { if (gradientUnits == null) { isObjectBoundingBox = @@ -356,7 +363,7 @@ class _Elements { final DrawableGradient? ref = parserState._definitions.getGradient('url($href)'); if (ref == null) { - reportMissingDef(href, 'linearGradient'); + reportMissingDef(parserState._key, href, 'linearGradient'); } else { if (gradientUnits == null) { isObjectBoundingBox = @@ -514,6 +521,7 @@ class _Elements { image, offset, parseStyle( + parserState._key, parserState.attributes, parserState._definitions, parserState.rootBounds, @@ -595,6 +603,7 @@ class _Elements { textInfos.add(_TextInfo( parseStyle( + parserState._key, parserState.attributes, parserState._definitions, parserState.rootBounds, @@ -867,6 +876,7 @@ class SvgParserState { getAttribute(attributes, 'id', def: ''), path, parseStyle( + _key, attributes, _definitions, path.getBounds(), diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 9245a81a087a..312181e6ade8 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -152,12 +152,17 @@ double? parseOpacity(List? attributes) { return null; } -DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri, - DrawableDefinitionServer definitions, Rect bounds, - {double? opacity}) { +DrawablePaint _getDefinitionPaint( + String? key, + PaintingStyle paintingStyle, + String iri, + DrawableDefinitionServer definitions, + Rect bounds, { + double? opacity, +}) { final Shader? shader = definitions.getShader(iri, bounds); if (shader == null) { - reportMissingDef(iri, '_getDefinitionPaint'); + reportMissingDef(key, iri, '_getDefinitionPaint'); } return DrawablePaint( @@ -169,6 +174,7 @@ DrawablePaint _getDefinitionPaint(PaintingStyle paintingStyle, String iri, /// Parses a @stroke attribute into a [Paint]. DrawablePaint? parseStroke( + String? key, List? attributes, Rect? bounds, DrawableDefinitionServer definitions, @@ -188,6 +194,7 @@ DrawablePaint? parseStroke( if (rawStroke.startsWith('url')) { return _getDefinitionPaint( + key, PaintingStyle.stroke, rawStroke, definitions, @@ -236,11 +243,13 @@ DrawablePaint? parseStroke( /// Parses a `fill` attribute. DrawablePaint? parseFill( - List? el, - Rect? bounds, - DrawableDefinitionServer definitions, - DrawablePaint? parentFill, - Color? defaultFillColor) { + String? key, + List? el, + Rect? bounds, + DrawableDefinitionServer definitions, + DrawablePaint? parentFill, + Color? defaultFillColor, +) { final String rawFill = getAttribute(el, 'fill')!; final String? rawFillOpacity = getAttribute(el, 'fill-opacity', def: '1.0'); final String? rawOpacity = getAttribute(el, 'opacity'); @@ -251,6 +260,7 @@ DrawablePaint? parseFill( if (rawFill.startsWith('url')) { return _getDefinitionPaint( + key, PaintingStyle.fill, rawFill, definitions, @@ -391,6 +401,7 @@ FontWeight? parseFontWeight(String? fontWeight) { /// /// Remember that @style attribute takes precedence. DrawableStyle parseStyle( + String? key, List? attributes, DrawableDefinitionServer definitions, Rect? bounds, @@ -399,10 +410,17 @@ DrawableStyle parseStyle( }) { return DrawableStyle.mergeAndBlend( parentStyle, - stroke: parseStroke(attributes, bounds, definitions, parentStyle?.stroke), + stroke: parseStroke( + key, + attributes, + bounds, + definitions, + parentStyle?.stroke, + ), dashArray: parseDashArray(attributes), dashOffset: parseDashOffset(attributes), fill: parseFill( + key, attributes, bounds, definitions, diff --git a/third_party/lib/src/utilities/errors.dart b/third_party/lib/src/utilities/errors.dart index ca94ce51d5f0..e16c76e823a7 100644 --- a/third_party/lib/src/utilities/errors.dart +++ b/third_party/lib/src/utilities/errors.dart @@ -1,7 +1,7 @@ import 'package:flutter/foundation.dart'; /// Reports a missing or undefined `` element. -void reportMissingDef(String? href, String methodName) { +void reportMissingDef(String? key, String? href, String methodName) { FlutterError.onError!( FlutterErrorDetails( exception: FlutterError.fromParts([ @@ -15,7 +15,7 @@ void reportMissingDef(String? href, String methodName) { ErrorDescription( 'This error is treated as non-fatal, but your SVG file will likely not render as intended'), ]), - context: ErrorDescription('in $methodName'), + context: ErrorDescription('while parsing $key in $methodName'), library: 'SVG', ), ); diff --git a/third_party/test/error_test.dart b/third_party/test/error_test.dart new file mode 100644 index 000000000000..d4e8803eb656 --- /dev/null +++ b/third_party/test/error_test.dart @@ -0,0 +1,31 @@ +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'package:flutter_svg/parser.dart'; + +void main() { + testWidgets('Reports tag in out of order defs', (WidgetTester tester) async { + final FlutterExceptionHandler oldHandler = FlutterError.onError!; + late FlutterErrorDetails error; + FlutterError.onError = (FlutterErrorDetails details) { + error = details; + }; + const String svgStr = ''' + + + + + + + + + +'''; + + final SvgParser parser = SvgParser(); + await parser.parse(svgStr, key: 'some_svg.svg'); + + expect(error.context.toString(), contains('while parsing some_svg.svg in _getDefinitionPaint')); + FlutterError.onError = oldHandler; + }); +} \ No newline at end of file From a9ec352cd905ed94a49efdf7a7944460f8bbcb73 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 23 Feb 2021 14:13:16 -0800 Subject: [PATCH 378/512] Fix sizing when no width or height are specified (#500) * Fix issue with the SvgPicture widget sizing when no width and height are specified Co-authored-by: ramsestom --- third_party/lib/src/picture_provider.dart | 3 +- third_party/lib/svg.dart | 93 +++++++-------- third_party/test/error_test.dart | 9 +- .../test/golden_widget/columns_and_rows.png | Bin 0 -> 25781 bytes .../golden_widget/flutter_logo.string.ltr.png | Bin 3404 -> 3396 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 3490 -> 3476 bytes third_party/test/no_width_height_test.dart | 106 ++++++++++++++++++ 7 files changed, 153 insertions(+), 58 deletions(-) create mode 100644 third_party/test/golden_widget/columns_and_rows.png create mode 100644 third_party/test/no_width_height_test.dart diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 7aaa6f9dfcc0..194a298477e7 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -53,8 +53,7 @@ PictureConfiguration createLocalPictureConfiguration( } return PictureConfiguration( bundle: context != null ? DefaultAssetBundle.of(context) : rootBundle, - locale: - context != null ? Localizations.maybeLocaleOf(context) : null, + locale: context != null ? Localizations.maybeLocaleOf(context) : null, textDirection: context != null ? Directionality.maybeOf(context) : null, viewBox: viewBox, platform: defaultTargetPlatform, diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 8a9b52925487..7fa258bc1dba 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -753,73 +753,60 @@ class _SvgPictureState extends State { @override Widget build(BuildContext context) { - Widget _maybeWrapWithSemantics(Widget child) { - if (widget.excludeFromSemantics) { - return child; - } - return Semantics( - container: widget.semanticsLabel != null, - image: true, - label: widget.semanticsLabel == null ? '' : widget.semanticsLabel, - child: child, - ); - } - - Widget _maybeWrapColorFilter(Widget child) { - // The color filter is already applied by the provider, or there is no - // color filter to apply at all. - if (widget.pictureProvider.colorFilter != null || - widget.colorFilter == null) { - return child; - } - return UnboundedColorFiltered( - colorFilter: widget.colorFilter, - child: child, - ); - } - + late Widget child; if (_picture != null) { final Rect viewport = Offset.zero & _picture!.viewport.size; double? width = widget.width; double? height = widget.height; - if (width == null && height == null) { - width = viewport.width; - height = viewport.height; - } else if (height != null) { + if (height != null && width == null) { width = height / viewport.height * viewport.width; - } else if (width != null) { + } else if (height == null && width != null) { height = width / viewport.width * viewport.height; } - return _maybeWrapWithSemantics( - _maybeWrapColorFilter( - SizedBox( - width: width, - height: height, - child: FittedBox( - fit: widget.fit, - alignment: widget.alignment, - clipBehavior: widget.clipBehavior, - child: SizedBox.fromSize( - size: viewport.size, - child: RawPicture( - _picture, - matchTextDirection: widget.matchTextDirection, - allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, - ), - ), - ), + child = FittedBox( + fit: widget.fit, + alignment: widget.alignment, + clipBehavior: widget.clipBehavior, + child: SizedBox.fromSize( + size: viewport.size, + child: RawPicture( + _picture, + matchTextDirection: widget.matchTextDirection, + allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, ), ), ); - } + if (width != null && height != null) { + child = SizedBox( + width: width, + height: height, + child: child, + ); + } - return _maybeWrapWithSemantics( - widget.placeholderBuilder == null + if (widget.pictureProvider.colorFilter == null && + widget.colorFilter != null) { + child = UnboundedColorFiltered( + colorFilter: widget.colorFilter, + child: child, + ); + } + } else { + child = widget.placeholderBuilder == null ? _getDefaultPlaceholder(context, widget.width, widget.height) - : widget.placeholderBuilder!(context), - ); + : widget.placeholderBuilder!(context); + } + if (!widget.excludeFromSemantics) { + child = Semantics( + container: widget.semanticsLabel != null, + image: true, + label: widget.semanticsLabel == null ? '' : widget.semanticsLabel, + child: child, + ); + } + return child; } Widget _getDefaultPlaceholder( diff --git a/third_party/test/error_test.dart b/third_party/test/error_test.dart index d4e8803eb656..98dad59e3e46 100644 --- a/third_party/test/error_test.dart +++ b/third_party/test/error_test.dart @@ -21,11 +21,14 @@ void main() { '''; - + final SvgParser parser = SvgParser(); await parser.parse(svgStr, key: 'some_svg.svg'); - expect(error.context.toString(), contains('while parsing some_svg.svg in _getDefinitionPaint')); + expect( + error.context.toString(), + contains('while parsing some_svg.svg in _getDefinitionPaint'), + ); FlutterError.onError = oldHandler; }); -} \ No newline at end of file +} diff --git a/third_party/test/golden_widget/columns_and_rows.png b/third_party/test/golden_widget/columns_and_rows.png new file mode 100644 index 0000000000000000000000000000000000000000..ffad57343e0b99518f7b3afee9a57b3ab78aa0ed GIT binary patch literal 25781 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 literal 0 HcmV?d00001 diff --git a/third_party/test/golden_widget/flutter_logo.string.ltr.png b/third_party/test/golden_widget/flutter_logo.string.ltr.png index e4402865634cfd5469cab823e5056404bd347fb8..354d79701da5b5e48490cdfcf5ab5b0e4c034970 100644 GIT binary patch literal 3396 zcmeH|`(KlF8^^!*K$(WJk)nb$9HJ&X4&`J+V2qsrMWhwzqf|5U15KBP!(4CTZmj;%nU>#MfFnnuryZL^tiao zO#A%L9gX*-k0g9D_*l3W68N_#P<``;CcR>?L5g@6wSi_m4e_G~_|n=$3tWD+n|2XG zf(e2hLbNDTJVL?N7!INQN-ua&T~+6mqS5DmT(e9)BxFtp;0lUz0DeYbR5$~u2Vepq3l!ZR0IC6;0Wjt(K=lq# z;~;<{O91`?bn=kOL~v&b0lBaDMw`+Q7H$iQJ)nq(B`b`I^Ey<{!)Z? z!g$+3SYV2$olUnuKW?BQ>wqNWyc}m*p4w`L)MNlG06_qJjlig&16Tq}OvDywg9u^O z?}5MdL_6fR!5dw21!*Nn^Ed+3cR`23LzWN(gIMWl zRJ|4q*^UqMAjK8nmfPAf_kvAUNkq$yslnUhaxN3e5L7BOd5KPDfFny-<9mxGhBz7E z_DW1T0TS$hI7Hbi)2XyQ|5VlJ#x@a_v*M-{vpPmXtmu#%NOJXTH)Qni2o>Xm~o{ zOBHX;^(`g3x$IcVo9XkUxt`sp^0!(DIvilCp7!0HIm=`#u1XK-9u_$|HvYHwdgJlq zW%EBx*BK0Fm`amy8BEeS$8Gd2w)6eZ$73BO@=B6eekn&TW>>xQ^p33l@t}x2fjQ5> z;ENcFV=0N+XHrVBe*dxA)Ud!_VlJ6X&eSEj+mKDmFN21ddqTM1aF23GQ|hB1>?_Td zCwO>k6+MUdR>cJfk*fq@qd7asV}@tRr*88<8+WOh{v`(H3$-!g1#Tc%o z(mnISc$=T2w5xfx!`1DDvV$GnUQ_V8{b7lu?Uiz)YN9Wv;S1`SF3WZ36`an29u`q{ zCxJJ9KX!hgU|%mWmXsqGu@A?!uZoD%UT*0B)%~Rt5f^*{n!9_)gZ||zi<I}EQlBtt~&@Og5Gr*tp$cNh9Q<0(J!W^_h4BH*)+n48QpJL+C1e=Kk@gfflZX e1QrsYmA$d>;7u-nqEWjT)9_~oF>2}IX@3FA@AN4E literal 3404 zcmeH|`&&|X9LK+hY%;A7Ej3qyNa}igGA~(E5#m7wGqu(-)6|-)P`fBzf@zY~25Lz% zua&deEZ1Y!R&!b|S47%W63Q%1%P2214ND``xzB0O{)+ki&q@lq9 z^G$3_5JK~LT+T*>=1>tLY$1LGq%<{aKU^@u#sD_D*tTR4Zj1zM-X7eyu+mVpJw$1M=DOs z_ZnF}I7;<8>8YsN!a0$BR!#SNO_H_y-wBEeG<)pF7r67}!6S+7-F$gTOLvi=t)c&v z%6Me#wa>Lbi+b|}G$>?t%{uUZcfhGO_Tlq8nhh>koHx6iTRYd(@vS3AZgC&`i zDp`PdA( z+54hSDZ;20eRIT7kntM_Uo=pFuox!*2LXJ9gCYP_0BZpl09b#AuyPjw+X0AhPzb;g zfHQzpx-V+VhAj~|fGi`tbR=7a5gH2>#z<&JMF})e^--2|iZN{CQFWuZ83I$F6Lz)l>{0dN4s0dN5DoCRCN zdK420F|r{>t_4O2-3~z$?OAAfAV`lJ5m|GkB&399&s*!T#x)jHv6ozjUz5yzCjU+<{zYOSrA-b}@EnUK@% zD@opARW+lX_oZEPe9g6Gy6^PJ$vEs13OwtqBlDfLS34YdJ}HKK!=^`D=fpTcXu9H# zrNWps2(^znz4Vvs5j6nE!IUzFB{{P#MFM0O5KhuDGw=(8R+_cucF@mOV!G_}I znp4rT0^SjD)&!glOgK*@gArncIn^Da#op6zsrRCgna3oxlclSjbXe$T5RqWWmYwOd z7dog9tjX`R5C%Z1^K|Hg%VpJZ+BTuW>k*q2Slsc zZT>dOlKRNs0L-g@XdxE=1Rh(Cw-c6AvX zgB5S|1NC8e30t9rRfQ4h$xoJoHRTiF(t1Yf4;j>lpjc}6Flwe(b=w$0*OgI*iHk)V z`f)4Qzs9PVJ!@uej%H5jYNirG$ZwE!G)R=ob+D1udwD+bjB4|VRZ5iH!pHtPmGwdX6Vt4K=k>JY_v$GN_jin8Adu87K(vC&TzzPvX)RVP=?4EY4rdXok1uxWI PNw^z4zhKTqc1+ek!J+%< diff --git a/third_party/test/golden_widget/flutter_logo.string.rtl.png b/third_party/test/golden_widget/flutter_logo.string.rtl.png index 6c8dd292777c2640514e08b937b8d3d764a80b9e..444bb28fdc8be4162c8069c9f5901feafe33162b 100644 GIT binary patch literal 3476 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[ + Row(children: const [ + ImageWithText(), + ]), + Row( + children: const [ + ImageWithText(), + ImageWithText(), + ], + ), + Row( + children: const [ + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ], + ), + Row( + children: const [ + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ], + ), + Row( + children: const [ + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ImageWithText(), + ], + ), + ], + ); + } +} + +class ImageWithText extends StatelessWidget { + const ImageWithText({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + final Widget image = SvgPicture.string(circleSvg); + final Widget imageContainer = Container( + child: image, + color: Colors.amber, + ); + const Widget text = Text('Hello'); + final Widget column = Column( + children: [ + imageContainer, + text, + ], + ); + return Expanded( + child: column, + ); + } +} + +const String circleSvg = ''' + + + + + + +'''; From d1cafd619c661546f7df0cbe03e471d052b62fd4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 23 Feb 2021 20:15:42 -0800 Subject: [PATCH 379/512] version bump/cleanup --- third_party/CHANGELOG.md | 9 +++++++++ third_party/lib/src/render_picture.dart | 1 - third_party/lib/src/unbounded_color_filtered.dart | 2 -- third_party/pubspec.yaml | 12 ++++++------ 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 4becfb6d7f4e..a9293866353f 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,14 @@ # CHANGES +## 0.21.0-nullsafety.0 + +- Fix sizing when both width and height are null. This is potentially breaking. +- Bump versions to stable nullsafe when possible +- Update README with links to alternative implementations of SVG in Flutter. +- Attempt to report file source/key when errors happen. +- Add missing platforms to example project, update Android embedding. +- Minor fixes for future error handling to respect new Dart rules/expectations. + ## 0.20.0-nullsafety.4 - Adds option `warningsAsErrors` that throws errors when detecting unsupported SVG elements. diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index 12e01ee7b47d..a1cfc2ad6cd2 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -1,7 +1,6 @@ import 'dart:math' as math; import 'package:flutter/widgets.dart'; -import 'package:meta/meta.dart'; import 'picture_stream.dart'; diff --git a/third_party/lib/src/unbounded_color_filtered.dart b/third_party/lib/src/unbounded_color_filtered.dart index 940be6e367a2..1787897ff4a7 100644 --- a/third_party/lib/src/unbounded_color_filtered.dart +++ b/third_party/lib/src/unbounded_color_filtered.dart @@ -1,8 +1,6 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:meta/meta.dart'; - /// Supports SvgPicture - not meant for public use, visible for testing. @visibleForTesting class UnboundedColorFiltered extends SingleChildRenderObjectWidget { diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 86e03ff8f19b..821fd031c558 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,22 +1,22 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 0.20.0-nullsafety.4 +version: 0.21.0-nullsafety.0 dependencies: flutter: sdk: flutter - meta: ^1.3.0-nullsafety.6 + meta: ^1.3.0 path_drawing: ^0.5.0-nullsafety.0 - vector_math: ^2.1.0-nullsafety.5 + vector_math: ^2.1.0 - xml: ^5.0.0-nullsafety.0 + xml: ^5.0.0 dev_dependencies: flutter_test: sdk: flutter - path: ^1.8.0-nullsafety.3 - test: ^1.16.0-nullsafety.9 + path: ^1.8.0 + test: ^1.16.0 environment: sdk: '>=2.12.0-0 <3.0.0' From db9ff7eb4f9add46401b6b806761cdbdbc907136 Mon Sep 17 00:00:00 2001 From: Meiwin Fu Date: Thu, 1 Apr 2021 01:59:02 +0800 Subject: [PATCH 380/512] Refactor attribute localName check (#525) Existing implementation uses replaceFirst API which will create a new String. This change replaces it with `localName` API of XmlEventAttribute which internally uses substring. The end result is overall faster parsing. --- third_party/lib/src/utilities/xml.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/lib/src/utilities/xml.dart b/third_party/lib/src/utilities/xml.dart index 50ea45057e1b..95eaf999e660 100644 --- a/third_party/lib/src/utilities/xml.dart +++ b/third_party/lib/src/utilities/xml.dart @@ -59,7 +59,7 @@ String _getAttribute( String? namespace, }) { for (XmlEventAttribute attr in list) { - if (attr.name.replaceFirst('${attr.namespacePrefix}:', '') == localName) { + if (attr.localName == localName) { return attr.value; } } From d270754f397f031b08770b595a798c5f7af0cad2 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 5 Apr 2021 11:24:22 -0700 Subject: [PATCH 381/512] missing docs --- third_party/example/lib/main.dart | 18 +++++----- third_party/lib/avd.dart | 43 +++++++++++++++--------- third_party/lib/src/avd/xml_parsers.dart | 9 ++++- third_party/lib/src/avd_parser.dart | 14 ++------ third_party/lib/svg.dart | 5 +-- 5 files changed, 49 insertions(+), 40 deletions(-) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index cf987d2eda45..09ebdd3d2cb9 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -1,4 +1,3 @@ -// ignore_for_file: public_member_api_docs import 'dart:ui'; import 'package:flutter/material.dart'; @@ -6,8 +5,7 @@ import 'package:flutter/rendering.dart'; import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; -/// Assets that will be rendered. -const List assetNames = [ +const List _assetNames = [ // 'assets/notfound.svg', // uncomment to test an asset that doesn't exist. 'assets/flutter_logo.svg', 'assets/dart.svg', @@ -61,10 +59,10 @@ const List uriNames = [ ]; void main() { - runApp(MyApp()); + runApp(_MyApp()); } -class MyApp extends StatelessWidget { +class _MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( @@ -72,20 +70,20 @@ class MyApp extends StatelessWidget { theme: ThemeData( primarySwatch: Colors.blue, ), - home: const MyHomePage(title: 'Flutter SVG Demo'), + home: const _MyHomePage(title: 'Flutter SVG Demo'), ); } } -class MyHomePage extends StatefulWidget { - const MyHomePage({Key? key, required this.title}) : super(key: key); +class _MyHomePage extends StatefulWidget { + const _MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override _MyHomePageState createState() => _MyHomePageState(); } -class _MyHomePageState extends State { +class _MyHomePageState extends State<_MyHomePage> { final List _painters = []; late double _dimension; @@ -93,7 +91,7 @@ class _MyHomePageState extends State { void initState() { super.initState(); _dimension = 203.0; - for (String assetName in assetNames) { + for (String assetName in _assetNames) { _painters.add( SvgPicture.asset(assetName), ); diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 31ef2599dae7..33c88f89a10a 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -1,4 +1,3 @@ -// ignore_for_file: public_member_api_docs import 'dart:convert'; import 'dart:typed_data'; import 'dart:ui' show Picture; @@ -14,11 +13,18 @@ import 'src/picture_provider.dart'; import 'src/picture_stream.dart'; import 'src/vector_drawable.dart'; +/// Instance for [Avd]'s utility methods, which can produce [DrawableRoot] or +/// [PictureInfo] objects from [String] and [Uint8List]s. final Avd avd = Avd._(); +/// A set of helper methods for decoding Android Vector Drawables to [Drawable]. +/// +/// AVD support is experimental and very incomplete. Use at your own risk. class Avd { Avd._(); + /// Decodes an Android Vector Drawable from a [Uint8List] to a [PictureInfo] + /// object. Future avdPictureDecoder( Uint8List raw, bool allowDrawingOutsideOfViewBox, @@ -31,6 +37,8 @@ class Avd { return PictureInfo(picture: pic, viewport: avdRoot.viewport.viewBoxRect); } + /// Decodes an Android Vector Drawable from a [String] to a [PictureInfo] + /// object. Future avdPictureStringDecoder( String raw, bool allowDrawingOutsideOfViewBox, @@ -47,6 +55,10 @@ class Avd { ); } + /// Produces a [Drawableroot] from a [Uint8List] of AVD byte data (assumes + /// UTF8 encoding). + /// + /// The `key` parameter is used for debugging purposes. Future fromAvdBytes(Uint8List raw, String key) async { // TODO(dnfield): do utf decoding in another thread? // Might just have to live with potentially slow(ish) decoding, this is causing errors. @@ -79,8 +91,13 @@ class Avd { } } -/// Extends [VectorDrawableImage] to parse SVG data to [Drawable]. +/// A widget that draws Android Vector Drawable data into a [Picture] using a +/// [PictureProvider]. +/// +/// Support for AVD is incomplete and experimental at this time. class AvdPicture extends SvgPicture { + /// Instantiates a widget that renders an SVG picture using the + /// `pictureProvider`. const AvdPicture( PictureProvider pictureProvider, { Key? key, @@ -97,6 +114,7 @@ class AvdPicture extends SvgPicture { colorFilter: colorFilter, ); + /// Draws an [AvdPicture] from a raw string of XML. AvdPicture.string(String bytes, {bool matchTextDirection = false, bool allowDrawingOutsideViewBox = false, @@ -117,6 +135,7 @@ class AvdPicture extends SvgPicture { placeholderBuilder: placeholderBuilder, key: key); + /// Draws an [AvdPicture] from an asset. AvdPicture.asset(String assetName, {Key? key, bool matchTextDirection = false, @@ -144,29 +163,23 @@ class AvdPicture extends SvgPicture { static ColorFilter? _getColorFilter(Color? color, BlendMode colorBlendMode) => color == null ? null : ColorFilter.mode(color, colorBlendMode); + /// A [PictureInfoDecoder] for [Uint8List]s that will clip to the viewBox. static final PictureInfoDecoder avdByteDecoder = (Uint8List bytes, ColorFilter? colorFilter, String key) => avd.avdPictureDecoder(bytes, false, colorFilter, key); + + /// A [PictureInfoDecoder] for strings that will clip to the viewBox. static final PictureInfoDecoder avdStringDecoder = (String data, ColorFilter? colorFilter, String key) => avd.avdPictureStringDecoder(data, false, colorFilter, key); + + /// A [PictureInfoDecoder] for [Uint8List]s that will not clip to the viewBox. static final PictureInfoDecoder avdByteDecoderOutsideViewBox = (Uint8List bytes, ColorFilter? colorFilter, String key) => avd.avdPictureDecoder(bytes, true, colorFilter, key); + + /// A [PictureInfoDecoder] for [String]s that will not clip to the viewBox. static final PictureInfoDecoder avdStringDecoderOutsideViewBox = (String data, ColorFilter? colorFilter, String key) => avd.avdPictureStringDecoder(data, true, colorFilter, key); } - -/// Creates a [DrawableRoot] from a string of SVG data. -DrawableRoot fromAvdString(String rawSvg, Rect size) { - final XmlElement svg = XmlDocument.parse(rawSvg).rootElement; - final DrawableViewport viewBox = parseViewBox(svg.attributes); - final List children = svg.children - .whereType() - .map((XmlElement child) => parseAvdElement(child, size)) - .toList(); - // todo : style on root - return DrawableRoot(getAttribute(svg.attributes, 'id', def: ''), viewBox, - children, DrawableDefinitionServer(), null); -} diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart index b35061be2cab..53afe5868172 100644 --- a/third_party/lib/src/avd/xml_parsers.dart +++ b/third_party/lib/src/avd/xml_parsers.dart @@ -1,4 +1,3 @@ -// ignore_for_file: public_member_api_docs import 'dart:math'; import 'dart:ui'; @@ -12,6 +11,7 @@ import '../vector_drawable.dart'; /// The AVD namespace. const String androidNS = 'http://schemas.android.com/apk/res/android'; +/// A utility method for getting an XML attribute with a default value. String? getAttribute( List attributes, String name, { @@ -43,6 +43,7 @@ DrawableViewport parseViewBox(List el) { ); } +/// Parses AVD transform related attributes to a [Matrix4]. Matrix4 parseTransform(List el) { final double rotation = parseDouble( getAttribute(el, 'rotation', def: '0', namespace: androidNS))!; @@ -66,6 +67,7 @@ Matrix4 parseTransform(List el) { ..translate(-pivotX + translateX, -pivotY + translateY); } +/// Parses an AVD stroke related attributes to a [DrawablePaint]. DrawablePaint? parseStroke(List el, Rect bounds) { final String? rawStroke = getAttribute(el, 'strokeColor', def: null, namespace: androidNS); @@ -84,11 +86,13 @@ DrawablePaint? parseStroke(List el, Rect bounds) { ); } +/// Parses AVD `strokeMiterLimit` to a double. double? parseMiterLimit(List el) { return parseDouble( getAttribute(el, 'strokeMiterLimit', def: '4', namespace: androidNS)); } +/// Parses AVD `strokeLineJoin` to a [StrokeJoin]. StrokeJoin parseStrokeJoin(List el) { final String? rawStrokeJoin = getAttribute(el, 'strokeLineJoin', def: 'miter', namespace: androidNS); @@ -104,6 +108,7 @@ StrokeJoin parseStrokeJoin(List el) { } } +/// Parses the `strokeLineCap` to a [StrokeCap]. StrokeCap parseStrokeCap(List el) { final String? rawStrokeCap = getAttribute(el, 'strokeLineCap', def: 'butt', namespace: androidNS); @@ -119,6 +124,7 @@ StrokeCap parseStrokeCap(List el) { } } +/// Parses fill information to a [DrawablePaint]. DrawablePaint? parseFill(List el, Rect bounds) { final String? rawFill = getAttribute(el, 'fillColor', def: null, namespace: androidNS); @@ -132,6 +138,7 @@ DrawablePaint? parseFill(List el, Rect bounds) { ); } +/// Turns a `fillType` into a [PathFillType]. PathFillType parsePathFillType(List el) { final String? rawFillType = getAttribute(el, 'fillType', def: 'nonZero', namespace: androidNS); diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart index d3adaf057f6c..37209a3fd674 100644 --- a/third_party/lib/src/avd_parser.dart +++ b/third_party/lib/src/avd_parser.dart @@ -1,4 +1,3 @@ -// ignore_for_file: public_member_api_docs import 'dart:ui'; import 'package:path_drawing/path_drawing.dart'; @@ -8,18 +7,9 @@ import 'package:xml/xml.dart'; import 'avd/xml_parsers.dart'; import 'vector_drawable.dart'; -class DrawableAvdRoot extends DrawableRoot { - const DrawableAvdRoot( - String id, - DrawableViewport viewBox, - List children, - DrawableDefinitionServer definitions, - DrawableStyle style) - : super(id, viewBox, children, definitions, style); -} - -/// An SVG Shape element that will be drawn to the canvas. +/// An AVD path element that will be drawn to the canvas. class DrawableAvdPath extends DrawableShape { + /// An AVD path element that will be drawn to the canvas. const DrawableAvdPath(String? id, Path path, DrawableStyle style) : super(id, path, style); diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 7fa258bc1dba..5a1558ead50b 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -89,9 +89,10 @@ class Svg { ); } - /// Produces a [Drawableroot] from a [Uint8List] of SVG byte data (assumes UTF8 encoding). + /// Produces a [Drawableroot] from a [Uint8List] of SVG byte data (assumes + /// UTF8 encoding). /// - /// The [key] will be used for debugging purposes. + /// The `key` will be used for debugging purposes. Future fromSvgBytes(Uint8List raw, String key) async { // TODO(dnfield): do utf decoding in another thread? // Might just have to live with potentially slow(ish) decoding, this is causing errors. From cc99d58446c07122ea81a3648f4658088972b5f4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 6 Apr 2021 16:07:14 -0700 Subject: [PATCH 382/512] Fix sizing issues (#529) --- third_party/CHANGELOG.md | 5 +++++ third_party/lib/svg.dart | 38 +++++++++++++++++++++----------------- third_party/pubspec.yaml | 2 +- 3 files changed, 27 insertions(+), 18 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index a9293866353f..f8e85d091674 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 0.21.0-nullsafety.1 + +- Fix bug introduced when width and height are both null on the widget. +- Use more efficient method for XML attribute parsing. + ## 0.21.0-nullsafety.0 - Fix sizing when both width and height are null. This is potentially breaking. diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 5a1558ead50b..d151f9453ae9 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -766,26 +766,30 @@ class _SvgPictureState extends State { height = width / viewport.width * viewport.height; } - child = FittedBox( - fit: widget.fit, - alignment: widget.alignment, - clipBehavior: widget.clipBehavior, - child: SizedBox.fromSize( - size: viewport.size, - child: RawPicture( - _picture, - matchTextDirection: widget.matchTextDirection, - allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, + if (height == null && width == null) { + height = viewport.height; + width = viewport.width; + } + assert(height != null); + assert(width != null); + + child = SizedBox( + width: width, + height: height, + child: FittedBox( + fit: widget.fit, + alignment: widget.alignment, + clipBehavior: widget.clipBehavior, + child: SizedBox.fromSize( + size: viewport.size, + child: RawPicture( + _picture, + matchTextDirection: widget.matchTextDirection, + allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, + ), ), ), ); - if (width != null && height != null) { - child = SizedBox( - width: width, - height: height, - child: child, - ); - } if (widget.pictureProvider.colorFilter == null && widget.colorFilter != null) { diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 821fd031c558..dd2e1c5d41fc 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 0.21.0-nullsafety.0 +version: 0.21.0-nullsafety.1 dependencies: flutter: From 4660e079b4f2c4aff7a89c2542ccc13b318441d1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 6 Apr 2021 16:15:54 -0700 Subject: [PATCH 383/512] stable nullsafe release --- third_party/CHANGELOG.md | 4 ++++ third_party/pubspec.yaml | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index f8e85d091674..03276c142cd0 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 0.21.0 + +- Stable nullsafe release. + ## 0.21.0-nullsafety.1 - Fix bug introduced when width and height are both null on the widget. diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index dd2e1c5d41fc..074f17004adb 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,13 +1,13 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 0.21.0-nullsafety.1 +version: 0.21.0 dependencies: flutter: sdk: flutter meta: ^1.3.0 - path_drawing: ^0.5.0-nullsafety.0 + path_drawing: ^0.5.0 vector_math: ^2.1.0 xml: ^5.0.0 @@ -19,7 +19,7 @@ dev_dependencies: test: ^1.16.0 environment: - sdk: '>=2.12.0-0 <3.0.0' + sdk: '>=2.12.0 <3.0.0' flutter: ">=1.24.0-6.0.pre" ## For developing features that require new functionality in engine: From d81c688aaa593224e99e2fb8125b55f4d8442f30 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 7 Apr 2021 11:48:32 -0700 Subject: [PATCH 384/512] Fix alignment issues again (#530) --- third_party/CHANGELOG.md | 4 ++++ third_party/lib/svg.dart | 14 +++++--------- third_party/pubspec.yaml | 2 +- .../golden_widget/flutter_logo.string.ltr.png | Bin 3396 -> 3404 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 3476 -> 3490 bytes 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 03276c142cd0..c3181d24600e 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 0.21.0+1 + +- Fix alignment/sizing issues introduced in 0.21.0 + ## 0.21.0 - Stable nullsafe release. diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index d151f9453ae9..7a7faca4d76d 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -760,19 +760,15 @@ class _SvgPictureState extends State { double? width = widget.width; double? height = widget.height; - if (height != null && width == null) { + if (width == null && height == null) { + width = viewport.width; + height = viewport.height; + } else if (height != null) { width = height / viewport.height * viewport.width; - } else if (height == null && width != null) { + } else if (width != null) { height = width / viewport.width * viewport.height; } - if (height == null && width == null) { - height = viewport.height; - width = viewport.width; - } - assert(height != null); - assert(width != null); - child = SizedBox( width: width, height: height, diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 074f17004adb..79193403285a 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 0.21.0 +version: 0.21.0+1 dependencies: flutter: diff --git a/third_party/test/golden_widget/flutter_logo.string.ltr.png b/third_party/test/golden_widget/flutter_logo.string.ltr.png index 354d79701da5b5e48490cdfcf5ab5b0e4c034970..e4402865634cfd5469cab823e5056404bd347fb8 100644 GIT binary patch literal 3404 zcmeH|`&&|X9LK+hY%;A7Ej3qyNa}igGA~(E5#m7wGqu(-)6|-)P`fBzf@zY~25Lz% zua&deEZ1Y!R&!b|S47%W63Q%1%P2214ND``xzB0O{)+ki&q@lq9 z^G$3_5JK~LT+T*>=1>tLY$1LGq%<{aKU^@u#sD_D*tTR4Zj1zM-X7eyu+mVpJw$1M=DOs z_ZnF}I7;<8>8YsN!a0$BR!#SNO_H_y-wBEeG<)pF7r67}!6S+7-F$gTOLvi=t)c&v z%6Me#wa>Lbi+b|}G$>?t%{uUZcfhGO_Tlq8nhh>koHx6iTRYd(@vS3AZgC&`i zDp`PdA( z+54hSDZ;20eRIT7kntM_Uo=pFuox!*2LXJ9gCYP_0BZpl09b#AuyPjw+X0AhPzb;g zfHQzpx-V+VhAj~|fGi`tbR=7a5gH2>#z<&JMF})e^--2|iZN{CQFWuZ83I$F6Lz)l>{0dN4s0dN5DoCRCN zdK420F|r{>t_4O2-3~z$?OAAfAV`lJ5m|GkB&399&s*!T#x)jHv6ozjUz5yzCjU+<{zYOSrA-b}@EnUK@% zD@opARW+lX_oZEPe9g6Gy6^PJ$vEs13OwtqBlDfLS34YdJ}HKK!=^`D=fpTcXu9H# zrNWps2(^znz4Vvs5j6nE!IUzFB{{P#MFM0O5KhuDGw=(8R+_cucF@mOV!G_}I znp4rT0^SjD)&!glOgK*@gArncIn^Da#op6zsrRCgna3oxlclSjbXe$T5RqWWmYwOd z7dog9tjX`R5C%Z1^K|Hg%VpJZ+BTuW>k*q2Slsc zZT>dOlKRNs0L-g@XdxE=1Rh(Cw-c6AvX zgB5S|1NC8e30t9rRfQ4h$xoJoHRTiF(t1Yf4;j>lpjc}6Flwe(b=w$0*OgI*iHk)V z`f)4Qzs9PVJ!@uej%H5jYNirG$ZwE!G)R=ob+D1udwD+bjB4|VRZ5iH!pHtPmGwdX6Vt4K=k>JY_v$GN_jin8Adu87K(vC&TzzPvX)RVP=?4EY4rdXok1uxWI PNw^z4zhKTqc1+ek!J+%< literal 3396 zcmeH|`(KlF8^^!*K$(WJk)nb$9HJ&X4&`J+V2qsrMWhwzqf|5U15KBP!(4CTZmj;%nU>#MfFnnuryZL^tiao zO#A%L9gX*-k0g9D_*l3W68N_#P<``;CcR>?L5g@6wSi_m4e_G~_|n=$3tWD+n|2XG zf(e2hLbNDTJVL?N7!INQN-ua&T~+6mqS5DmT(e9)BxFtp;0lUz0DeYbR5$~u2Vepq3l!ZR0IC6;0Wjt(K=lq# z;~;<{O91`?bn=kOL~v&b0lBaDMw`+Q7H$iQJ)nq(B`b`I^Ey<{!)Z? z!g$+3SYV2$olUnuKW?BQ>wqNWyc}m*p4w`L)MNlG06_qJjlig&16Tq}OvDywg9u^O z?}5MdL_6fR!5dw21!*Nn^Ed+3cR`23LzWN(gIMWl zRJ|4q*^UqMAjK8nmfPAf_kvAUNkq$yslnUhaxN3e5L7BOd5KPDfFny-<9mxGhBz7E z_DW1T0TS$hI7Hbi)2XyQ|5VlJ#x@a_v*M-{vpPmXtmu#%NOJXTH)Qni2o>Xm~o{ zOBHX;^(`g3x$IcVo9XkUxt`sp^0!(DIvilCp7!0HIm=`#u1XK-9u_$|HvYHwdgJlq zW%EBx*BK0Fm`amy8BEeS$8Gd2w)6eZ$73BO@=B6eekn&TW>>xQ^p33l@t}x2fjQ5> z;ENcFV=0N+XHrVBe*dxA)Ud!_VlJ6X&eSEj+mKDmFN21ddqTM1aF23GQ|hB1>?_Td zCwO>k6+MUdR>cJfk*fq@qd7asV}@tRr*88<8+WOh{v`(H3$-!g1#Tc%o z(mnISc$=T2w5xfx!`1DDvV$GnUQ_V8{b7lu?Uiz)YN9Wv;S1`SF3WZ36`an29u`q{ zCxJJ9KX!hgU|%mWmXsqGu@A?!uZoD%UT*0B)%~Rt5f^*{n!9_)gZ||zi<I}EQlBtt~&@Og5Gr*tp$cNh9Q<0(J!W^_h4BH*)+n48QpJL+C1e=Kk@gfflZX e1QrsYmA$d>;7u-nqEWjT)9_~oF>2}IX@3FA@AN4E diff --git a/third_party/test/golden_widget/flutter_logo.string.rtl.png b/third_party/test/golden_widget/flutter_logo.string.rtl.png index 444bb28fdc8be4162c8069c9f5901feafe33162b..6c8dd292777c2640514e08b937b8d3d764a80b9e 100644 GIT binary patch literal 3490 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 Date: Wed, 21 Apr 2021 22:58:22 -0700 Subject: [PATCH 385/512] expose cache on PictureProvider so that users can change the limit (#538) --- third_party/.cirrus.yml | 16 ++--- third_party/CHANGELOG.md | 10 ++- third_party/lib/src/picture_cache.dart | 5 +- third_party/lib/src/picture_provider.dart | 19 +++--- third_party/pubspec.yaml | 2 +- third_party/test/picture_cache_test.dart | 80 ++++++++++++++++++----- third_party/test/widget_svg_test.dart | 24 +++---- 7 files changed, 102 insertions(+), 54 deletions(-) diff --git a/third_party/.cirrus.yml b/third_party/.cirrus.yml index 34c0d628be4d..331c96ee8444 100644 --- a/third_party/.cirrus.yml +++ b/third_party/.cirrus.yml @@ -1,6 +1,3 @@ -container: - image: cirrusci/flutter:latest - env: CI_NAME: "CirrusCI" CI_BUILD_NUMBER: $CIRRUS_TASK_ID @@ -10,15 +7,10 @@ env: COVERALLS_REPO_TOKEN: ENCRYPTED[61ba3fee193a9ed6116e0f61bbe26fe8c0452287e5dfd86c728e2f1f24327818d6c74c956d7b9cbf3bd6236489af0fd1] test_task: - matrix: - - name: stable - channel_script: | - flutter channel stable - flutter upgrade - - name: master - channel_script: | - flutter channel master - flutter upgrade + container: + matrix: + - image: cirrusci/flutter:dev + - image: cirrusci/flutter:stable pub_cache: folder: ~/.pub-cache analyze_script: flutter analyze . diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index c3181d24600e..2e662c8b0b50 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGES +## 0.22.0 + +- Expose `PictureCache` on `PictureProvider`, and deprecate + `PictureProvider.cacheCount` and `PictureProvider.clearCache`. This is + intended to allow users to set a maximum cache size, which was previously + impossible. + ## 0.21.0+1 - Fix alignment/sizing issues introduced in 0.21.0 @@ -24,7 +31,8 @@ ## 0.20.0-nullsafety.4 -- Adds option `warningsAsErrors` that throws errors when detecting unsupported SVG elements. +- Adds option `warningsAsErrors` that throws errors when detecting unsupported + SVG elements. ## 0.20.0-nullsafety.3 diff --git a/third_party/lib/src/picture_cache.dart b/third_party/lib/src/picture_cache.dart index 158bebddece9..a06d7a2c0d6e 100644 --- a/third_party/lib/src/picture_cache.dart +++ b/third_party/lib/src/picture_cache.dart @@ -3,7 +3,8 @@ import 'picture_stream.dart'; const int _kDefaultSize = 1000; /// A cache for [Picture] objects. -// TODO(dnfield): Implement memory based limiting, once `approximateByteCount` is exposed in engine +/// +/// By default, this caches up to 1000 objects. class PictureCache { final Map _cache = {}; @@ -41,8 +42,6 @@ class PictureCache { /// /// This is useful if, for instance, the root asset bundle has been updated /// and therefore new images must be obtained. - // TODO(ianh): Provide a way to target individual images. This is currently non-trivial - // because by the time we get to the imageCache, the keys we're using are opaque. void clear() { _cache.clear(); } diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 194a298477e7..926e91c9763a 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -201,9 +201,6 @@ class PictureConfiguration { } } -// TODO(dnfield): allow other people to implement this. -PictureCache _cache = PictureCache(); - /// Identifies a picture without committing to the precise final asset. This /// allows a set of pictures to be identified and for the precise picture to later /// be resolved based on the environment, e.g. the device pixel ratio. @@ -304,11 +301,17 @@ abstract class PictureProvider { /// const constructors so that they can be used in const expressions. const PictureProvider(this.colorFilter); - /// The number of items in the [PictureCache]. - static int get cacheCount => _cache.count; + /// The [PictureCache] for [Picture] objects created by [PictureProvider] + /// implementations. + static final PictureCache cache = PictureCache(); + + /// The number of items in the [cache]. + @Deprecated('Use the `cache` object directly instead.') + static int get cacheCount => cache.count; - /// Clears the [PictureCache]. - static void clearCache() => _cache.clear(); + /// Clears the [cache]. + @Deprecated('Use the `cache` object directly instead.') + static void clearCache() => cache.clear(); /// The color filter to apply to the picture, if any. final ColorFilter? colorFilter; @@ -330,7 +333,7 @@ abstract class PictureProvider { (T key) { obtainedKey = key; stream.setCompleter( - _cache.putIfAbsent( + cache.putIfAbsent( key!, () => load(key, onError: onError), ), diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 79193403285a..4443e4269470 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 0.21.0+1 +version: 0.22.0 dependencies: flutter: diff --git a/third_party/test/picture_cache_test.dart b/third_party/test/picture_cache_test.dart index 3bd917c6bc76..f2f0e328ea86 100644 --- a/third_party/test/picture_cache_test.dart +++ b/third_party/test/picture_cache_test.dart @@ -8,19 +8,64 @@ import 'package:xml/xml.dart'; class MockPictureStreamCompleter extends PictureStreamCompleter {} void main() { - late PictureCache cache; - + const String svgString = ''' + + + +'''; + + const String svgString2 = ''' + + + +'''; + + const String svgString3 = ''' + + + +'''; + + late int previousMaximumSize; setUp(() { - cache = PictureCache(); + PictureProvider.cache.clear(); + previousMaximumSize = PictureProvider.cache.maximumSize; + }); + + tearDown(() { + PictureProvider.cache.maximumSize = previousMaximumSize; + }); + + testWidgets('Can set a limit on the PictureCache', + (WidgetTester tester) async { + expect(PictureProvider.cache.count, 0); + + PictureProvider.cache.maximumSize = 2; + expect(PictureProvider.cache.count, 0); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: SvgPicture.string(svgString), + )); + expect(PictureProvider.cache.count, 1); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: SvgPicture.string(svgString2), + )); + expect(PictureProvider.cache.count, 2); + + await tester.pumpWidget(Directionality( + textDirection: TextDirection.ltr, + child: SvgPicture.string(svgString3), + )); + expect(PictureProvider.cache.count, 2); + + PictureProvider.cache.maximumSize = 1; + expect(PictureProvider.cache.count, 1); }); testWidgets('Precache test', (WidgetTester tester) async { - const String svgString = ''' - -'''; - const String svgString2 = ''' - -'''; await tester.pumpWidget( const Directionality( textDirection: TextDirection.ltr, @@ -28,7 +73,7 @@ void main() { ), ); - expect(PictureProvider.cacheCount, 0); + expect(PictureProvider.cache.count, 0); await precachePicture( StringPicture( SvgPicture.svgStringDecoder, @@ -36,7 +81,7 @@ void main() { ), tester.element(find.text('test_text')), ); - expect(PictureProvider.cacheCount, 1); + expect(PictureProvider.cache.count, 1); await tester.pumpWidget( Directionality( @@ -44,7 +89,7 @@ void main() { child: SvgPicture.string(svgString), ), ); - expect(PictureProvider.cacheCount, 1); + expect(PictureProvider.cache.count, 1); await tester.pumpWidget( Directionality( @@ -52,10 +97,10 @@ void main() { child: SvgPicture.string(svgString2), ), ); - expect(PictureProvider.cacheCount, 2); + expect(PictureProvider.cache.count, 2); - PictureProvider.clearCache(); - expect(PictureProvider.cacheCount, 0); + PictureProvider.cache.clear(); + expect(PictureProvider.cache.count, 0); }); testWidgets('Precache - null context', (WidgetTester tester) async { @@ -63,7 +108,7 @@ void main() { '''; - expect(PictureProvider.cacheCount, 0); + expect(PictureProvider.cache.count, 0); await precachePicture( StringPicture( SvgPicture.svgStringDecoder, @@ -71,7 +116,7 @@ void main() { ), null, ); - expect(PictureProvider.cacheCount, 1); + expect(PictureProvider.cache.count, 1); }); testWidgets('Precache with error', (WidgetTester tester) async { @@ -104,6 +149,7 @@ void main() { }); test('Cache Tests', () { + final PictureCache cache = PictureCache(); expect(cache.maximumSize, equals(1000)); cache.maximumSize = 1; expect(cache.maximumSize, equals(1)); diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 7a295798540a..1f3ce21b4418 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -22,7 +22,7 @@ void main() { late FakeHttpClientRequest fakeRequest; late FakeHttpClient fakeHttpClient; setUp(() { - PictureProvider.clearCache(); + PictureProvider.cache.clear(); svg.cacheColorFilterOverride = null; fakeResponse = FakeHttpClientResponse(); fakeRequest = FakeHttpClientRequest(fakeResponse); @@ -32,7 +32,7 @@ void main() { testWidgets( 'SvgPicture does not use a color filtering widget when no color specified', (WidgetTester tester) async { - expect(PictureProvider.cacheCount, 0); + expect(PictureProvider.cache.count, 0); await tester.pumpWidget( SvgPicture.string( svgStr, @@ -41,13 +41,13 @@ void main() { ), ); await tester.pumpAndSettle(); - expect(PictureProvider.cacheCount, 1); + expect(PictureProvider.cache.count, 1); expect(find.byType(UnboundedColorFiltered), findsNothing); }); testWidgets('SvgPicture does not invalidate the cache when color changes', (WidgetTester tester) async { - expect(PictureProvider.cacheCount, 0); + expect(PictureProvider.cache.count, 0); await tester.pumpWidget( SvgPicture.string( svgStr, @@ -57,7 +57,7 @@ void main() { ), ); - expect(PictureProvider.cacheCount, 1); + expect(PictureProvider.cache.count, 1); await tester.pumpWidget( SvgPicture.string( @@ -68,13 +68,13 @@ void main() { ), ); - expect(PictureProvider.cacheCount, 1); + expect(PictureProvider.cache.count, 1); }); testWidgets( 'SvgPicture does invalidate the cache when color changes and color filter is cached', (WidgetTester tester) async { - expect(PictureProvider.cacheCount, 0); + expect(PictureProvider.cache.count, 0); await tester.pumpWidget( SvgPicture.string( svgStr, @@ -85,7 +85,7 @@ void main() { ), ); - expect(PictureProvider.cacheCount, 1); + expect(PictureProvider.cache.count, 1); await tester.pumpWidget( SvgPicture.string( @@ -97,14 +97,14 @@ void main() { ), ); - expect(PictureProvider.cacheCount, 2); + expect(PictureProvider.cache.count, 2); }); testWidgets( 'SvgPicture does invalidate the cache when color changes and color filter is cached (override)', (WidgetTester tester) async { svg.cacheColorFilterOverride = true; - expect(PictureProvider.cacheCount, 0); + expect(PictureProvider.cache.count, 0); await tester.pumpWidget( SvgPicture.string( svgStr, @@ -114,7 +114,7 @@ void main() { ), ); - expect(PictureProvider.cacheCount, 1); + expect(PictureProvider.cache.count, 1); await tester.pumpWidget( SvgPicture.string( @@ -125,7 +125,7 @@ void main() { ), ); - expect(PictureProvider.cacheCount, 2); + expect(PictureProvider.cache.count, 2); }); testWidgets('SvgPicture can work with a FittedBox', From fffa330bd4698c0f9a976142a98fbf7077d35337 Mon Sep 17 00:00:00 2001 From: jefflim-google <52889965+jefflim-google@users.noreply.github.com> Date: Wed, 5 May 2021 16:15:54 +0800 Subject: [PATCH 386/512] Improve performance of SVG parsing (#546) * Improve performance of SVG parsing The previous code used to iterate through a list of XmlEventAttributes for every call to getAttribute. The newer code constructs a Map, and looks up the attribute name directly. This seems to show a 30% overall reduction to svg parsing costs. * Fix lint issues highlighted by github * Fix typo --- third_party/lib/src/svg/parser_state.dart | 37 +++++++-------- third_party/lib/src/svg/xml_parsers.dart | 27 ++++++----- third_party/lib/src/utilities/numbers.dart | 2 +- third_party/lib/src/utilities/xml.dart | 32 +++++++------ third_party/test/xml_svg_test.dart | 53 +++++++++++----------- 5 files changed, 77 insertions(+), 74 deletions(-) diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index 42cfa96f696e..d72b61bfa568 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -18,7 +18,7 @@ final Set _unhandledElements = {'title', 'desc'}; typedef _ParseFunc = Future? Function( SvgParserState parserState, bool warningsAsErrors); -typedef _PathFunc = Path? Function(List? attributes); +typedef _PathFunc = Path? Function(Map attributes); const Map _svgElementParsers = { 'svg': _Elements.svg, @@ -635,7 +635,7 @@ class _Elements { } class _Paths { - static Path circle(List? attributes) { + static Path circle(Map attributes) { final double cx = parseDouble(getAttribute(attributes, 'cx', def: '0'))!; final double cy = parseDouble(getAttribute(attributes, 'cy', def: '0'))!; final double r = parseDouble(getAttribute(attributes, 'r', def: '0'))!; @@ -643,12 +643,12 @@ class _Paths { return Path()..addOval(oval); } - static Path path(List? attributes) { + static Path path(Map attributes) { final String d = getAttribute(attributes, 'd')!; return parseSvgPathData(d); } - static Path rect(List? attributes) { + static Path rect(Map attributes) { final double x = parseDouble(getAttribute(attributes, 'x', def: '0'))!; final double y = parseDouble(getAttribute(attributes, 'y', def: '0'))!; final double w = parseDouble(getAttribute(attributes, 'width', def: '0'))!; @@ -669,16 +669,16 @@ class _Paths { return Path()..addRect(rect); } - static Path? polygon(List? attributes) { + static Path? polygon(Map attributes) { return parsePathFromPoints(attributes, true); } - static Path? polyline(List? attributes) { + static Path? polyline(Map attributes) { return parsePathFromPoints(attributes, false); } static Path? parsePathFromPoints( - List? attributes, bool close) { + Map attributes, bool close) { final String? points = getAttribute(attributes, 'points'); if (points == '') { return null; @@ -688,7 +688,7 @@ class _Paths { return parseSvgPathData(path); } - static Path ellipse(List? attributes) { + static Path ellipse(Map attributes) { final double cx = parseDouble(getAttribute(attributes, 'cx', def: '0'))!; final double cy = parseDouble(getAttribute(attributes, 'cy', def: '0'))!; final double rx = parseDouble(getAttribute(attributes, 'rx', def: '0'))!; @@ -698,7 +698,7 @@ class _Paths { return Path()..addOval(r); } - static Path line(List? attributes) { + static Path line(Map attributes) { final double x1 = parseDouble(getAttribute(attributes, 'x1', def: '0'))!; final double x2 = parseDouble(getAttribute(attributes, 'x2', def: '0'))!; final double y1 = parseDouble(getAttribute(attributes, 'y1', def: '0'))!; @@ -734,7 +734,7 @@ class SvgParserState { final Queue<_SvgGroupTuple> _parentDrawables = ListQueue<_SvgGroupTuple>(10); DrawableRoot? _root; bool _inDefs = false; - List? _currentAttributes; + late Map _currentAttributes; XmlStartElementEvent? _currentStartElement; /// The current depth of the reader in the XML hierarchy. @@ -750,7 +750,7 @@ class SvgParserState { depth -= 1; assert(depth >= 0); } - _currentAttributes = []; + _currentAttributes = {}; _currentStartElement = null; if (depth < subtreeStartDepth) { return; @@ -764,8 +764,9 @@ class SvgParserState { final XmlEvent event = _eventIterator.current; bool isSelfClosing = false; if (event is XmlStartElementEvent) { - if (getAttribute(event.attributes, 'display') == 'none' || - getAttribute(event.attributes, 'visibility') == 'hidden') { + final Map attributeMap = event.attributes.toAttributeMap(); + if (getAttribute(attributeMap, 'display') == 'none' || + getAttribute(attributeMap, 'visibility') == 'hidden') { print('SVG Warning: Discarding:\n\n $event\n\n' 'and any children it has since it is not visible.\n' 'If that element is meant to be visible, the `display` or ' @@ -778,7 +779,7 @@ class SvgParserState { } continue; } - _currentAttributes = event.attributes; + _currentAttributes = attributeMap; _currentStartElement = event; depth += 1; isSelfClosing = event.isSelfClosing; @@ -788,7 +789,7 @@ class SvgParserState { if (isSelfClosing || event is XmlEndElementEvent) { depth -= 1; assert(depth >= 0); - _currentAttributes = []; + _currentAttributes = {}; _currentStartElement = null; } if (depth < subtreeStartDepth) { @@ -826,11 +827,11 @@ class SvgParserState { } /// The XML Attributes of the current node in the tree. - List? get attributes => _currentAttributes; + Map get attributes => _currentAttributes; /// Gets the attribute for the current position of the parser. - String? attribute(String name, {String? def, String? namespace}) => - getAttribute(attributes, name, def: def, namespace: namespace); + String? attribute(String name, {String? def}) => + getAttribute(attributes, name, def: def); /// The current group, if any, in the [Drawable] heirarchy. DrawableParent? get currentGroup { diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 312181e6ade8..3fdbb145ee55 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -2,7 +2,6 @@ import 'dart:ui'; import 'package:path_drawing/path_drawing.dart'; import 'package:vector_math/vector_math_64.dart'; -import 'package:xml/xml_events.dart'; import '../utilities/errors.dart'; import '../utilities/numbers.dart'; @@ -38,7 +37,7 @@ double _parseRawWidthHeight(String? raw) { /// The [respectWidthHeight] parameter specifies whether `width` and `height` attributes /// on the root SVG element should be treated in accordance with the specification. DrawableViewport? parseViewBox( - List? svg, { + Map svg, { bool nullOk = false, }) { final String? viewBox = getAttribute(svg, 'viewBox'); @@ -86,14 +85,14 @@ DrawableViewport? parseViewBox( } /// Builds an IRI in the form of `'url(#id)'`. -String buildUrlIri(List? attributes) => +String buildUrlIri(Map attributes) => 'url(#${getAttribute(attributes, 'id')})'; /// An empty IRI. const String emptyUrlIri = 'url(#)'; /// Parses a `spreadMethod` attribute into a [TileMode]. -TileMode parseTileMode(List? attributes) { +TileMode parseTileMode(Map attributes) { final String? spreadMethod = getAttribute(attributes, 'spreadMethod', def: 'pad'); switch (spreadMethod) { @@ -112,7 +111,7 @@ TileMode parseTileMode(List? attributes) { /// /// Does not currently support percentages. CircularIntervalList? parseDashArray( - List? attributes, + Map attributes, ) { final String? rawDashArray = getAttribute(attributes, 'stroke-dasharray'); if (rawDashArray == '') { @@ -127,7 +126,7 @@ CircularIntervalList? parseDashArray( } /// Parses a @stroke-dashoffset into a [DashOffset]. -DashOffset? parseDashOffset(List? attributes) { +DashOffset? parseDashOffset(Map attributes) { final String? rawDashOffset = getAttribute(attributes, 'stroke-dashoffset'); if (rawDashOffset == '') { return null; @@ -144,7 +143,7 @@ DashOffset? parseDashOffset(List? attributes) { } /// Parses an @opacity value into a [double], clamped between 0..1. -double? parseOpacity(List? attributes) { +double? parseOpacity(Map attributes) { final String? rawOpacity = getAttribute(attributes, 'opacity', def: null); if (rawOpacity != null) { return parseDouble(rawOpacity)!.clamp(0.0, 1.0).toDouble(); @@ -175,7 +174,7 @@ DrawablePaint _getDefinitionPaint( /// Parses a @stroke attribute into a [Paint]. DrawablePaint? parseStroke( String? key, - List? attributes, + Map attributes, Rect? bounds, DrawableDefinitionServer definitions, DrawablePaint? parentStroke, @@ -244,7 +243,7 @@ DrawablePaint? parseStroke( /// Parses a `fill` attribute. DrawablePaint? parseFill( String? key, - List? el, + Map el, Rect? bounds, DrawableDefinitionServer definitions, DrawablePaint? parentFill, @@ -304,14 +303,14 @@ Color? _determineFillColor( } /// Parses a `fill-rule` attribute into a [PathFillType]. -PathFillType? parseFillRule(List? attributes, +PathFillType? parseFillRule(Map attributes, [String attr = 'fill-rule', String? def = 'nonzero']) { final String? rawFillRule = getAttribute(attributes, attr, def: def); return parseRawFillRule(rawFillRule); } /// Applies a transform to a path if the [attributes] contain a `transform`. -Path? applyTransformIfNeeded(Path? path, List? attributes) { +Path? applyTransformIfNeeded(Path? path, Map attributes) { final Matrix4? transform = parseTransform(getAttribute(attributes, 'transform', def: null)); @@ -324,7 +323,7 @@ Path? applyTransformIfNeeded(Path? path, List? attributes) { /// Parses a `clipPath` element into a list of [Path]s. List? parseClipPath( - List? attributes, + Map attributes, DrawableDefinitionServer definitions, ) { final String? rawClipAttribute = getAttribute(attributes, 'clip-path'); @@ -355,7 +354,7 @@ const Map _blendModes = { /// Lookup the mask if the attribute is present. DrawableStyleable? parseMask( - List? attributes, + Map attributes, DrawableDefinitionServer definitions, ) { final String? rawMaskAttribute = getAttribute(attributes, 'mask'); @@ -402,7 +401,7 @@ FontWeight? parseFontWeight(String? fontWeight) { /// Remember that @style attribute takes precedence. DrawableStyle parseStyle( String? key, - List? attributes, + Map attributes, DrawableDefinitionServer definitions, Rect? bounds, DrawableStyle? parentStyle, { diff --git a/third_party/lib/src/utilities/numbers.dart b/third_party/lib/src/utilities/numbers.dart index 7e05b47a9a95..fc3e174475f4 100644 --- a/third_party/lib/src/utilities/numbers.dart +++ b/third_party/lib/src/utilities/numbers.dart @@ -8,7 +8,7 @@ double? parseDouble(String? maybeDouble, {bool tryParse = false}) { if (maybeDouble == null) { return null; } - maybeDouble = maybeDouble.trim().replaceFirst('px', '').trim(); + maybeDouble = maybeDouble.replaceFirst('px', '').trim(); if (tryParse) { return double.tryParse(maybeDouble); } diff --git a/third_party/lib/src/utilities/xml.dart b/third_party/lib/src/utilities/xml.dart index 95eaf999e660..018972b5eee1 100644 --- a/third_party/lib/src/utilities/xml.dart +++ b/third_party/lib/src/utilities/xml.dart @@ -7,10 +7,9 @@ const String kXlinkNamespace = 'http://www.w3.org/1999/xlink'; /// /// SVG 1.1 specifies that these attributes should be in the xlink namespace. /// SVG 2 deprecates that namespace. -String? getHrefAttribute(List? attributes) => getAttribute( +String? getHrefAttribute(Map attributes) => getAttribute( attributes, 'href', - namespace: kXlinkNamespace, def: getAttribute(attributes, 'href'), ); @@ -19,15 +18,14 @@ String? getHrefAttribute(List? attributes) => getAttribute( /// /// Will look to the style first if it can. String? getAttribute( - List? el, + Map el, String name, { String? def = '', - String? namespace, bool checkStyle = true, }) { String raw = ''; if (checkStyle) { - final String? style = _getAttribute(el!, 'style').trim(); + final String? style = _getAttribute(el, 'style'); if (style != '' && style != null) { // Probably possible to slightly optimize this (e.g. use indexOf instead of split), // but handling potential whitespace will get complicated and this just works. @@ -43,25 +41,29 @@ String? getAttribute( } if (raw == '') { - raw = _getAttribute(el, name, namespace: namespace).trim(); + raw = _getAttribute(el, name); } } else { - raw = _getAttribute(el!, name, namespace: namespace).trim(); + raw = _getAttribute(el, name); } return raw == '' ? def : raw; } String _getAttribute( - List list, + Map attributes, String localName, { String def = '', - String? namespace, }) { - for (XmlEventAttribute attr in list) { - if (attr.localName == localName) { - return attr.value; - } - } - return def; + return attributes[localName] ?? def; +} + +/// Extension on List for easy conversion to an attribute +/// map. +extension AttributeMapXmlEventAttributeExtension on List { + /// Converts the List to an attribute map. + Map toAttributeMap() => { + for (final XmlEventAttribute attribute in this) + attribute.localName: attribute.value.trim(), + }; } diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index f8cccfc98a6a..a2b8cdbfc21b 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -17,8 +17,8 @@ void main() { 'xlink:href="http://localhost" />') .first as XmlStartElementEvent; - expect(getHrefAttribute(el.attributes), 'http://localhost'); - expect(getHrefAttribute(elXlink.attributes), 'http://localhost'); + expect(getHrefAttribute(el.attributes.toAttributeMap()), 'http://localhost'); + expect(getHrefAttribute(elXlink.attributes.toAttributeMap()), 'http://localhost'); }); test('Attribute and style tests', () { @@ -27,15 +27,16 @@ void main() { 'style="stroke-opacity:1;fill-opacity:.23" />') .first as XmlStartElementEvent; - expect(getAttribute(el.attributes, 'stroke'), '#fff'); - expect(getAttribute(el.attributes, 'fill'), '#eee'); - expect(getAttribute(el.attributes, 'stroke-dashpattern'), '1 2'); - expect(getAttribute(el.attributes, 'stroke-opacity'), '1'); - expect(getAttribute(el.attributes, 'stroke-another'), ''); - expect(getAttribute(el.attributes, 'fill-opacity'), '.23'); + final Map attributes = el.attributes.toAttributeMap(); + expect(getAttribute(attributes, 'stroke'), '#fff'); + expect(getAttribute(attributes, 'fill'), '#eee'); + expect(getAttribute(attributes, 'stroke-dashpattern'), '1 2'); + expect(getAttribute(attributes, 'stroke-opacity'), '1'); + expect(getAttribute(attributes, 'stroke-another'), ''); + expect(getAttribute(attributes, 'fill-opacity'), '.23'); - expect(getAttribute(el.attributes, 'fill-opacity', checkStyle: false), ''); - expect(getAttribute(el.attributes, 'fill', checkStyle: false), '#eee'); + expect(getAttribute(attributes, 'fill-opacity', checkStyle: false), ''); + expect(getAttribute(attributes, 'fill', checkStyle: false), '#eee'); }); // if the parsing logic changes, we can simplify some methods. for now assert that whitespace in attributes is preserved @@ -76,17 +77,17 @@ void main() { final XmlStartElementEvent svgWithNoSizeInfo = parseEvents('').first as XmlStartElementEvent; - expect(parseViewBox(svgWithViewBoxAndWidthHeight.attributes)!.size, + expect(parseViewBox(svgWithViewBoxAndWidthHeight.attributes.toAttributeMap())!.size, const Size(50, 50)); - expect(parseViewBox(svgWithViewBox.attributes)!.viewBoxRect, rect); - expect(parseViewBox(svgWithViewBox.attributes)!.viewBoxOffset, Offset.zero); - expect(parseViewBox(svgWithViewBoxAndWidthHeight.attributes)!.viewBoxRect, + expect(parseViewBox(svgWithViewBox.attributes.toAttributeMap())!.viewBoxRect, rect); + expect(parseViewBox(svgWithViewBox.attributes.toAttributeMap())!.viewBoxOffset, Offset.zero); + expect(parseViewBox(svgWithViewBoxAndWidthHeight.attributes.toAttributeMap())!.viewBoxRect, rect); - expect(parseViewBox(svgWithWidthHeight.attributes)!.viewBoxRect, rect); - expect(parseViewBox(svgWithNoSizeInfo.attributes, nullOk: true), null); - expect(() => parseViewBox(svgWithNoSizeInfo.attributes), throwsStateError); - expect(parseViewBox(svgWithViewBoxMinXMinY.attributes)!.viewBoxRect, rect); - expect(parseViewBox(svgWithViewBoxMinXMinY.attributes)!.viewBoxOffset, + expect(parseViewBox(svgWithWidthHeight.attributes.toAttributeMap())!.viewBoxRect, rect); + expect(parseViewBox(svgWithNoSizeInfo.attributes.toAttributeMap(), nullOk: true), null); + expect(() => parseViewBox(svgWithNoSizeInfo.attributes.toAttributeMap()), throwsStateError); + expect(parseViewBox(svgWithViewBoxMinXMinY.attributes.toAttributeMap())!.viewBoxRect, rect); + expect(parseViewBox(svgWithViewBoxMinXMinY.attributes.toAttributeMap())!.viewBoxOffset, const Offset(-42.0, -56.0)); }); @@ -107,12 +108,12 @@ void main() { final XmlStartElementEvent none = parseEvents('').first as XmlStartElementEvent; - expect(parseTileMode(pad.attributes), TileMode.clamp); - expect(parseTileMode(invalid.attributes), TileMode.clamp); - expect(parseTileMode(none.attributes), TileMode.clamp); + expect(parseTileMode(pad.attributes.toAttributeMap()), TileMode.clamp); + expect(parseTileMode(invalid.attributes.toAttributeMap()), TileMode.clamp); + expect(parseTileMode(none.attributes.toAttributeMap()), TileMode.clamp); - expect(parseTileMode(reflect.attributes), TileMode.mirror); - expect(parseTileMode(repeat.attributes), TileMode.repeated); + expect(parseTileMode(reflect.attributes.toAttributeMap()), TileMode.mirror); + expect(parseTileMode(repeat.attributes.toAttributeMap()), TileMode.repeated); }); test('@stroke-dashoffset tests', () { @@ -124,8 +125,8 @@ void main() { as XmlStartElementEvent; // TODO(dnfield): DashOffset is completely opaque right now, maybe expose the raw value? - expect(parseDashOffset(abs.attributes), isNotNull); - expect(parseDashOffset(pct.attributes), isNotNull); + expect(parseDashOffset(abs.attributes.toAttributeMap()), isNotNull); + expect(parseDashOffset(pct.attributes.toAttributeMap()), isNotNull); }); test('font-weight tests', () { From 2136ce7d05154cb6760764f9cb14cb0c12ac27a0 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 5 May 2021 01:51:18 -0700 Subject: [PATCH 387/512] version bumps (#547) * version bumps * fix coverage for non-write users --- third_party/.cirrus.yml | 4 +--- third_party/CHANGELOG.md | 5 +++++ third_party/pubspec.yaml | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/third_party/.cirrus.yml b/third_party/.cirrus.yml index 331c96ee8444..938eb3901740 100644 --- a/third_party/.cirrus.yml +++ b/third_party/.cirrus.yml @@ -15,6 +15,4 @@ test_task: folder: ~/.pub-cache analyze_script: flutter analyze . test_script: flutter test --coverage - coveralls_script: | - dart pub global activate coveralls - dart pub global run coveralls coverage/lcov.info + coveralls_script: ./.ci/coveralls.sh diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 2e662c8b0b50..f464bfcc65bc 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 0.22.1 + +- Pick up performance improvements in path_parsing 0.2.1 +- Performance improvements in XML parsing of SVGs. + ## 0.22.0 - Expose `PictureCache` on `PictureProvider`, and deprecate diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 4443e4269470..d49128d8e4ad 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 0.22.0 +version: 0.22.1 dependencies: flutter: From 2c5faf2ab08ce3b350db20c93a23938a0e461f47 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 5 May 2021 01:52:22 -0700 Subject: [PATCH 388/512] missing bump --- third_party/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index d49128d8e4ad..153f7a90bde1 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -7,7 +7,7 @@ dependencies: flutter: sdk: flutter meta: ^1.3.0 - path_drawing: ^0.5.0 + path_drawing: ^0.5.1 vector_math: ^2.1.0 xml: ^5.0.0 From c47e261903ff91a06a36d76f3a2a9dbe9f15a99f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 May 2021 10:08:45 -0700 Subject: [PATCH 389/512] sort directives --- third_party/test/error_test.dart | 4 ++-- third_party/test/widget_svg_test.dart | 5 +++-- third_party/test/xml_svg_test.dart | 4 ++-- third_party/tool/gen_golden.dart | 5 ++--- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/third_party/test/error_test.dart b/third_party/test/error_test.dart index 98dad59e3e46..97e5220c6fd0 100644 --- a/third_party/test/error_test.dart +++ b/third_party/test/error_test.dart @@ -1,8 +1,8 @@ import 'package:flutter/foundation.dart'; -import 'package:flutter_test/flutter_test.dart'; - import 'package:flutter_svg/parser.dart'; +import 'package:flutter_test/flutter_test.dart'; + void main() { testWidgets('Reports tag in out of order defs', (WidgetTester tester) async { final FlutterExceptionHandler oldHandler = FlutterError.onError!; diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 1f3ce21b4418..ed89f9fe9520 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -5,11 +5,12 @@ import 'dart:typed_data'; import 'dart:ui' show window; import 'package:flutter/rendering.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/src/unbounded_color_filtered.dart'; + import 'package:flutter_test/flutter_test.dart'; -import 'package:flutter_svg/flutter_svg.dart'; Future _checkWidgetAndGolden(Key key, String filename) async { final Finder widgetFinder = find.byKey(key); diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index a2b8cdbfc21b..6bfeece031ac 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -1,10 +1,10 @@ import 'dart:ui'; +import 'package:flutter_svg/src/svg/xml_parsers.dart'; +import 'package:flutter_svg/src/utilities/xml.dart'; import 'package:test/test.dart'; import 'package:xml/xml_events.dart'; -import 'package:flutter_svg/src/svg/xml_parsers.dart'; -import 'package:flutter_svg/src/utilities/xml.dart'; void main() { test('Xlink href tests', () { diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index d5731d3085a1..79eb8725d942 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -9,10 +9,9 @@ import 'dart:io'; import 'dart:typed_data'; import 'dart:ui'; -import 'package:path/path.dart' as path; - -import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/src/vector_drawable.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:path/path.dart' as path; Future getSvgPngBytes(String svgData) async { final PictureRecorder rec = PictureRecorder(); From 09c1753b600f1d91ef4c4e523d27979a781ff2e6 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 May 2021 16:44:48 -0700 Subject: [PATCH 390/512] skip golden test on non-linux --- third_party/test/no_width_height_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/test/no_width_height_test.dart b/third_party/test/no_width_height_test.dart index 7532b40c92df..3efffbbb45b1 100644 --- a/third_party/test/no_width_height_test.dart +++ b/third_party/test/no_width_height_test.dart @@ -19,7 +19,7 @@ void main() { find.byType(RepaintBoundary), matchesGoldenFile('golden_widget/columns_and_rows.png'), ); - }); + }, skip: !isLinux); } class ColumnsAndRows extends StatelessWidget { From 1e7976cd2cfa4dda60fe220b5b5cc3401948ab5d Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Tue, 18 May 2021 12:25:29 -0700 Subject: [PATCH 391/512] Update for the latest Dart analyze unnecessary_import check (#555) --- third_party/example/lib/main.dart | 3 --- third_party/test/picture_cache_test.dart | 1 - 2 files changed, 4 deletions(-) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index 09ebdd3d2cb9..fc29e6178a8a 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -1,7 +1,4 @@ -import 'dart:ui'; - import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; diff --git a/third_party/test/picture_cache_test.dart b/third_party/test/picture_cache_test.dart index f2f0e328ea86..2876fb38fcf9 100644 --- a/third_party/test/picture_cache_test.dart +++ b/third_party/test/picture_cache_test.dart @@ -1,7 +1,6 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/src/picture_cache.dart'; -import 'package:flutter_svg/src/picture_provider.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:xml/xml.dart'; From db087a11165657a151c644997dcd3dd9af850482 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Sousa?= Date: Sun, 23 May 2021 13:04:17 -0300 Subject: [PATCH 392/512] Implemented text-style parser (#556) * font-style attribute parser --- third_party/example/assets/simple/text_4.svg | 22 +++++++++++++++++++ third_party/golden/simple/text_4.png | Bin 0 -> 1022 bytes third_party/lib/src/svg/xml_parsers.dart | 19 ++++++++++++++++ third_party/test/xml_svg_test.dart | 9 ++++++++ 4 files changed, 50 insertions(+) create mode 100644 third_party/example/assets/simple/text_4.svg create mode 100644 third_party/golden/simple/text_4.png diff --git a/third_party/example/assets/simple/text_4.svg b/third_party/example/assets/simple/text_4.svg new file mode 100644 index 000000000000..4348492e7d44 --- /dev/null +++ b/third_party/example/assets/simple/text_4.svg @@ -0,0 +1,22 @@ + + + + Example text04 - Font style + + + Normal text + + Italic text + + + Oblique text + + + Italic bold text + diff --git a/third_party/golden/simple/text_4.png b/third_party/golden/simple/text_4.png new file mode 100644 index 0000000000000000000000000000000000000000..03bf13c643200da41e5c8813f4218db0daa86c31 GIT binary patch literal 1022 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_tI8o-U3d6?5L+-JK;CD8TTb^F~M43jYU7gIRKemUvFoT3ae5fBf9JbK-#> z!W?3c*79WPT#Q#=&<--df_=T~UhkT` zk0ayi%UkMqZmg(1Hs{!#vQ1ZWJhxv7R? znfY(BuD&;McZt~{@bTs4{mJ+D$=2O7eBB~e^!su%yQjHWcG>NA{@C)8E2aMP`SvU4 z=AJb#J2SVkdiVO+mlk$;%lCO#z6yzLj@czr_%`au^Ye%IKR?#{^H|@`$M4^L+o~-a zzHUqK{iS=pZkl|LBY*F$6!pCmBl7o3g;uAX{uZ{Z70AAos=l`|V)whZKqU;X`^#>6 z<||zLwK&oA`PQ7zh1?sj$>*-VrO+?WuRm|G{k!|`v%i0ReKNlLPMv&v``@kMe?uqV z-mcu&rxdrRV@LJ&XEQ%nebst&W@df;-%n5fJ$`-t|MRM>S;cwg`Tu?_c_#d1c{_i5 z`KxEoYLdTydltQU=@YY)ZVwM06iGjuo}CSf8eP@xul_f^y}iAo_<7bm!}W&`cbq-@ zwNNs9+mt)2>>Z8H%?|!)dVJl)jcMK|*H$&#)Z5vVosiYYeseGG$j!}%lYlYlxid6> zLeA%BA=8W&ub*tYeO2~^9tdyx8O80Z{84zklXCBwEbi}*jmiskU!(4?bZ@V;*zb?Y zM~-%X?%7*c`-5LC`s}o6(O+u?W(faxV8@yuai&xzGO`9x%b)c7j9jr?P3Mm5T>+Wk M>FVdQ&MBb@0Pi-<#{d8T literal 0 HcmV?d00001 diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 3fdbb145ee55..d24681ce1799 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -396,6 +396,22 @@ FontWeight? parseFontWeight(String? fontWeight) { ' is not supported'); } +/// Parses a `font-style` attribute value into a [FontStyle]. +FontStyle? parseFontStyle(String? fontStyle) { + if (fontStyle == null) { + return null; + } + switch (fontStyle) { + case 'normal': + return FontStyle.normal; + case 'italic': + case 'oblique': + return FontStyle.italic; + } + throw UnsupportedError('Attribute value for font-style="$fontStyle"' + ' is not supported'); +} + /// Parses style attributes or @style attribute. /// /// Remember that @style attribute takes precedence. @@ -443,6 +459,9 @@ DrawableStyle parseStyle( fontWeight: parseFontWeight( getAttribute(attributes, 'font-weight', def: null), ), + fontStyle: parseFontStyle( + getAttribute(attributes, 'font-style', def: null), + ), anchor: parseTextAnchor( getAttribute(attributes, 'text-anchor', def: 'inherit'), ), diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index 6bfeece031ac..95804b188c79 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -145,4 +145,13 @@ void main() { expect(() => parseFontWeight('invalid'), throwsUnsupportedError); }); + + test('font-style tests', () { + expect(parseFontStyle('normal'), FontStyle.normal); + expect(parseFontStyle('italic'), FontStyle.italic); + expect(parseFontStyle('oblique'), FontStyle.italic); + + expect(parseFontStyle(null), isNull); + expect(() => parseFontStyle('invalid'), throwsUnsupportedError); + }); } From 04b15f4f0a1a8f50bc849d3980b6e839acf597ec Mon Sep 17 00:00:00 2001 From: Niklas Schulze Date: Thu, 27 May 2021 19:58:46 +0200 Subject: [PATCH 393/512] Add text-decoration support (#562) * Add text-decoration support * add golden Co-authored-by: Dan Field --- third_party/example/assets/simple/text_5.svg | 21 ++++++ third_party/example/lib/main.dart | 1 + third_party/golden/simple/text_5.png | Bin 0 -> 570 bytes third_party/lib/src/svg/xml_parsers.dart | 54 ++++++++++++++- third_party/test/xml_svg_test.dart | 69 +++++++++++++++---- 5 files changed, 130 insertions(+), 15 deletions(-) create mode 100644 third_party/example/assets/simple/text_5.svg create mode 100644 third_party/golden/simple/text_5.png diff --git a/third_party/example/assets/simple/text_5.svg b/third_party/example/assets/simple/text_5.svg new file mode 100644 index 000000000000..63f711fb196a --- /dev/null +++ b/third_party/example/assets/simple/text_5.svg @@ -0,0 +1,21 @@ + + + Example text05 - Text decoration + + + Overline text + + + Strike text + + + Underline text + + diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index fc29e6178a8a..6a1cc8c06aa5 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -14,6 +14,7 @@ const List _assetNames = [ 'assets/simple/group_opacity.svg', 'assets/simple/text.svg', 'assets/simple/text_2.svg', + 'assets/simple/text_5.svg', 'assets/simple/linear_gradient.svg', 'assets/simple/linear_gradient_2.svg', 'assets/simple/male.svg', diff --git a/third_party/golden/simple/text_5.png b/third_party/golden/simple/text_5.png new file mode 100644 index 0000000000000000000000000000000000000000..8fee9037fb906df539f45c31fad1e94bc9e09a8a GIT binary patch literal 570 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>pxhHr7srr_IdAV8`b9g6I9xPz$@DCH{B%R7$iz(?Q`RWlKI!*j#fk}YrZMG7 zCCvMDUb8-N@1g69^ZTE#X9XHZ0?2<{vNJ|+cYDLib!GevlQ~(M927WM4lTdS{O9uD zzwbCLHhjFF^w;k0JGn+?Y55Z`w^TFrow4O$X><@Eg^;L!bN-F8>W}-8jtV{TjxxUw z7yJ8X$Hwpf`+DCuyUk5FOl$cV?R)L#^LLyQPp;43y6)cNUD&bHdn6`;Y=tqk;ejGGXwq-RZ_jE~dmkX|B<}AeN(o01MGX z;-C6U*MH`HXOX$_$HC72-Mj`+NNks1Z}W@YuA%v{!Vb@N1pyMm9H_K`|AV+ii0<#@ Svp!~lbb7k_xvX svg, { + Map svg, { bool nullOk = false, }) { final String? viewBox = getAttribute(svg, 'viewBox'); @@ -243,7 +243,7 @@ DrawablePaint? parseStroke( /// Parses a `fill` attribute. DrawablePaint? parseFill( String? key, - Map el, + Map el, Rect? bounds, DrawableDefinitionServer definitions, DrawablePaint? parentFill, @@ -412,6 +412,47 @@ FontStyle? parseFontStyle(String? fontStyle) { ' is not supported'); } +/// Parses a `text-decoration` attribute value into a [TextDecoration]. +TextDecoration? parseTextDecoration(String? textDecoration) { + if (textDecoration == null) { + return null; + } + switch (textDecoration) { + case 'none': + return TextDecoration.none; + case 'underline': + return TextDecoration.underline; + case 'overline': + return TextDecoration.overline; + case 'line-through': + return TextDecoration.lineThrough; + } + throw UnsupportedError('Attribute value for text-decoration="$textDecoration"' + ' is not supported'); +} + +/// Parses a `text-decoration-style` attribute value into a [TextDecorationStyle]. +TextDecorationStyle? parseTextDecorationStyle(String? textDecorationStyle) { + if (textDecorationStyle == null) { + return null; + } + switch (textDecorationStyle) { + case 'solid': + return TextDecorationStyle.solid; + case 'dashed': + return TextDecorationStyle.dashed; + case 'dotted': + return TextDecorationStyle.dotted; + case 'double': + return TextDecorationStyle.double; + case 'wavy': + return TextDecorationStyle.wavy; + } + throw UnsupportedError( + 'Attribute value for text-decoration-style="$textDecorationStyle"' + ' is not supported'); +} + /// Parses style attributes or @style attribute. /// /// Remember that @style attribute takes precedence. @@ -465,6 +506,15 @@ DrawableStyle parseStyle( anchor: parseTextAnchor( getAttribute(attributes, 'text-anchor', def: 'inherit'), ), + decoration: parseTextDecoration( + getAttribute(attributes, 'text-decoration', def: null), + ), + decorationColor: parseColor( + getAttribute(attributes, 'text-decoration-color', def: null), + ), + decorationStyle: parseTextDecorationStyle( + getAttribute(attributes, 'text-decoration-style', def: null), + ), ), blendMode: _blendModes[getAttribute(attributes, 'mix-blend-mode')!], ); diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index 95804b188c79..0243aaab624d 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -5,7 +5,6 @@ import 'package:flutter_svg/src/utilities/xml.dart'; import 'package:test/test.dart'; import 'package:xml/xml_events.dart'; - void main() { test('Xlink href tests', () { final XmlStartElementEvent el = @@ -17,8 +16,10 @@ void main() { 'xlink:href="http://localhost" />') .first as XmlStartElementEvent; - expect(getHrefAttribute(el.attributes.toAttributeMap()), 'http://localhost'); - expect(getHrefAttribute(elXlink.attributes.toAttributeMap()), 'http://localhost'); + expect( + getHrefAttribute(el.attributes.toAttributeMap()), 'http://localhost'); + expect(getHrefAttribute(elXlink.attributes.toAttributeMap()), + 'http://localhost'); }); test('Attribute and style tests', () { @@ -77,17 +78,37 @@ void main() { final XmlStartElementEvent svgWithNoSizeInfo = parseEvents('').first as XmlStartElementEvent; - expect(parseViewBox(svgWithViewBoxAndWidthHeight.attributes.toAttributeMap())!.size, + expect( + parseViewBox(svgWithViewBoxAndWidthHeight.attributes.toAttributeMap())! + .size, const Size(50, 50)); - expect(parseViewBox(svgWithViewBox.attributes.toAttributeMap())!.viewBoxRect, rect); - expect(parseViewBox(svgWithViewBox.attributes.toAttributeMap())!.viewBoxOffset, Offset.zero); - expect(parseViewBox(svgWithViewBoxAndWidthHeight.attributes.toAttributeMap())!.viewBoxRect, + expect( + parseViewBox(svgWithViewBox.attributes.toAttributeMap())!.viewBoxRect, + rect); + expect( + parseViewBox(svgWithViewBox.attributes.toAttributeMap())!.viewBoxOffset, + Offset.zero); + expect( + parseViewBox(svgWithViewBoxAndWidthHeight.attributes.toAttributeMap())! + .viewBoxRect, + rect); + expect( + parseViewBox(svgWithWidthHeight.attributes.toAttributeMap())! + .viewBoxRect, + rect); + expect( + parseViewBox(svgWithNoSizeInfo.attributes.toAttributeMap(), + nullOk: true), + null); + expect(() => parseViewBox(svgWithNoSizeInfo.attributes.toAttributeMap()), + throwsStateError); + expect( + parseViewBox(svgWithViewBoxMinXMinY.attributes.toAttributeMap())! + .viewBoxRect, rect); - expect(parseViewBox(svgWithWidthHeight.attributes.toAttributeMap())!.viewBoxRect, rect); - expect(parseViewBox(svgWithNoSizeInfo.attributes.toAttributeMap(), nullOk: true), null); - expect(() => parseViewBox(svgWithNoSizeInfo.attributes.toAttributeMap()), throwsStateError); - expect(parseViewBox(svgWithViewBoxMinXMinY.attributes.toAttributeMap())!.viewBoxRect, rect); - expect(parseViewBox(svgWithViewBoxMinXMinY.attributes.toAttributeMap())!.viewBoxOffset, + expect( + parseViewBox(svgWithViewBoxMinXMinY.attributes.toAttributeMap())! + .viewBoxOffset, const Offset(-42.0, -56.0)); }); @@ -113,7 +134,8 @@ void main() { expect(parseTileMode(none.attributes.toAttributeMap()), TileMode.clamp); expect(parseTileMode(reflect.attributes.toAttributeMap()), TileMode.mirror); - expect(parseTileMode(repeat.attributes.toAttributeMap()), TileMode.repeated); + expect( + parseTileMode(repeat.attributes.toAttributeMap()), TileMode.repeated); }); test('@stroke-dashoffset tests', () { @@ -154,4 +176,25 @@ void main() { expect(parseFontStyle(null), isNull); expect(() => parseFontStyle('invalid'), throwsUnsupportedError); }); + + test('text-decoration tests', () { + expect(parseTextDecoration('none'), TextDecoration.none); + expect(parseTextDecoration('line-through'), TextDecoration.lineThrough); + expect(parseTextDecoration('overline'), TextDecoration.overline); + expect(parseTextDecoration('underline'), TextDecoration.underline); + + expect(parseTextDecoration(null), isNull); + expect(() => parseTextDecoration('invalid'), throwsUnsupportedError); + }); + + test('text-decoration-style tests', () { + expect(parseTextDecorationStyle('solid'), TextDecorationStyle.solid); + expect(parseTextDecorationStyle('dashed'), TextDecorationStyle.dashed); + expect(parseTextDecorationStyle('dotted'), TextDecorationStyle.dotted); + expect(parseTextDecorationStyle('double'), TextDecorationStyle.double); + expect(parseTextDecorationStyle('wavy'), TextDecorationStyle.wavy); + + expect(parseTextDecorationStyle(null), isNull); + expect(() => parseTextDecorationStyle('invalid'), throwsUnsupportedError); + }); } From 1ee9864b7fb8454a93d8c013bbdf9c65d01a112a Mon Sep 17 00:00:00 2001 From: Niklas Schulze Date: Tue, 1 Jun 2021 17:59:12 +0200 Subject: [PATCH 394/512] Add support for xml:space (#563) --- third_party/lib/src/svg/parser_state.dart | 16 ++++++++++++---- third_party/test/svg_parsers_test.dart | 15 +++++++++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index d72b61bfa568..28891752457a 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -20,6 +20,8 @@ typedef _ParseFunc = Future? Function( SvgParserState parserState, bool warningsAsErrors); typedef _PathFunc = Path? Function(Map attributes); +final RegExp _trimPattern = RegExp(r'[\r|\n|\t]'); + const Map _svgElementParsers = { 'svg': _Elements.svg, 'g': _Elements.g, @@ -623,7 +625,13 @@ class _Elements { if (event is XmlCDATAEvent) { _processText(event.text.trim()); } else if (event is XmlTextEvent) { - _processText(event.text.trim()); + final String? space = + getAttribute(parserState.attributes, 'space', def: null); + if (space != 'preserve') { + _processText(event.text.trim()); + } else { + _processText(event.text.replaceAll(_trimPattern, '')); + } } if (event is XmlStartElementEvent) { _processStartElement(event); @@ -677,8 +685,7 @@ class _Paths { return parsePathFromPoints(attributes, false); } - static Path? parsePathFromPoints( - Map attributes, bool close) { + static Path? parsePathFromPoints(Map attributes, bool close) { final String? points = getAttribute(attributes, 'points'); if (points == '') { return null; @@ -764,7 +771,8 @@ class SvgParserState { final XmlEvent event = _eventIterator.current; bool isSelfClosing = false; if (event is XmlStartElementEvent) { - final Map attributeMap = event.attributes.toAttributeMap(); + final Map attributeMap = + event.attributes.toAttributeMap(); if (getAttribute(attributeMap, 'display') == 'none' || getAttribute(attributeMap, 'visibility') == 'hidden') { print('SVG Warning: Discarding:\n\n $event\n\n' diff --git a/third_party/test/svg_parsers_test.dart b/third_party/test/svg_parsers_test.dart index f87b02be65c3..a6f1e5ba9af6 100644 --- a/third_party/test/svg_parsers_test.dart +++ b/third_party/test/svg_parsers_test.dart @@ -258,4 +258,19 @@ void main() { final SvgParser parser = SvgParser(); expect(await parser.parse(svgStr), isA()); }); + + test('Respects whitespace attribute', () async { + const String svgStr = ''' + + + +'''; + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse(svgStr); + + expect(find(root, 'preserve-space') != null, true); + // Empty text elements get removed + expect(find(root, 'remove-space') != null, false); + }); } From d22408531b9828120e243969dbeb28f7e068dc3b Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Thu, 15 Jul 2021 09:31:40 -0700 Subject: [PATCH 395/512] change golden file compares to allow +/- 1 in color components (#575) * change golden file compares to allow +/- 1 in color components * accept format results (only for files changed here) * explicitly require rawRgba bytes --- third_party/test/golden_svg_test.dart | 21 ++++++++++++++++----- third_party/tool/gen_golden.dart | 17 ++++++++++++++--- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/third_party/test/golden_svg_test.dart b/third_party/test/golden_svg_test.dart index e72e43a90d6f..dc0eaef07829 100644 --- a/third_party/test/golden_svg_test.dart +++ b/third_party/test/golden_svg_test.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'dart:typed_data'; +import 'dart:ui'; import 'package:path/path.dart'; @@ -28,16 +29,26 @@ String getSvgAssetName(String goldenFileName) { .replaceAll('.png', '.svg'); } +bool colorComponentsSimilar(int a, int b) => (a - b).abs() <= 1; + void main() { test('SVG Rendering matches golden files', () async { for (File goldenFile in getGoldenFileNames()) { final File svgAssetFile = File(getSvgAssetName(goldenFile.path)); final Uint8List bytes = - await golden.getSvgPngBytes(await svgAssetFile.readAsString()); - - final Uint8List goldenBytes = await goldenFile.readAsBytes(); - - expect(bytes, orderedEquals(goldenBytes), + await golden.getSvgRgbaBytes(await svgAssetFile.readAsString()); + + final Codec testImageCodec = + await instantiateImageCodec(await goldenFile.readAsBytes()); + final Image testImage = (await testImageCodec.getNextFrame()).image; + final ByteData? goldenRgba = + await testImage.toByteData(format: ImageByteFormat.rawRgba); + final Uint8List goldenBytes = goldenRgba!.buffer.asUint8List(); + + expect( + bytes, + pairwiseCompare(goldenBytes, colorComponentsSimilar, + 'components nearly equal to'), reason: '${goldenFile.path} does not match rendered output of ${svgAssetFile.path}!'); } diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index 79eb8725d942..afb04a1d99f9 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -13,7 +13,7 @@ import 'package:flutter_svg/src/vector_drawable.dart'; import 'package:flutter_svg/svg.dart'; import 'package:path/path.dart' as path; -Future getSvgPngBytes(String svgData) async { +Future getSvgImage(String svgData) async { final PictureRecorder rec = PictureRecorder(); final Canvas canvas = Canvas(rec); @@ -29,13 +29,24 @@ Future getSvgPngBytes(String svgData) async { final Picture pict = rec.endRecording(); - final Image image = - await pict.toImage(size.width.toInt(), size.height.toInt()); + return await pict.toImage(size.width.toInt(), size.height.toInt()); +} + +Future getSvgPngBytes(String svgData) async { + final Image image = await getSvgImage(svgData); final ByteData bytes = (await image.toByteData(format: ImageByteFormat.png))!; return bytes.buffer.asUint8List(); } +Future getSvgRgbaBytes(String svgData) async { + final Image image = await getSvgImage(svgData); + final ByteData bytes = + (await image.toByteData(format: ImageByteFormat.rawRgba))!; + + return bytes.buffer.asUint8List(); +} + Iterable getSvgFileNames() sync* { final Directory dir = Directory('./example/assets'); for (FileSystemEntity fe in dir.listSync(recursive: true)) { From a2deca0d60c1ff1bb55c66d8548b4c5884cd1127 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 16 Aug 2021 11:09:30 -0700 Subject: [PATCH 396/512] pub get --- third_party/.cirrus.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/third_party/.cirrus.yml b/third_party/.cirrus.yml index 938eb3901740..c1dfcb3ac300 100644 --- a/third_party/.cirrus.yml +++ b/third_party/.cirrus.yml @@ -11,8 +11,7 @@ test_task: matrix: - image: cirrusci/flutter:dev - image: cirrusci/flutter:stable - pub_cache: - folder: ~/.pub-cache + pub_script: flutter pub get analyze_script: flutter analyze . test_script: flutter test --coverage coveralls_script: ./.ci/coveralls.sh From e414bbf2aa2e2ed9c313e1864dcf7d1b5d5a0083 Mon Sep 17 00:00:00 2001 From: Nikita Mishkov Date: Mon, 16 Aug 2021 21:29:43 +0300 Subject: [PATCH 397/512] Unused parameter `bounds` of method draw() (#584) * updated README --- third_party/lib/src/utilities/xml.dart | 6 +++--- third_party/lib/src/vector_drawable.dart | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/third_party/lib/src/utilities/xml.dart b/third_party/lib/src/utilities/xml.dart index 018972b5eee1..61a57cf6220d 100644 --- a/third_party/lib/src/utilities/xml.dart +++ b/third_party/lib/src/utilities/xml.dart @@ -63,7 +63,7 @@ String _getAttribute( extension AttributeMapXmlEventAttributeExtension on List { /// Converts the List to an attribute map. Map toAttributeMap() => { - for (final XmlEventAttribute attribute in this) - attribute.localName: attribute.value.trim(), - }; + for (final XmlEventAttribute attribute in this) + attribute.localName: attribute.value.trim(), + }; } diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 8016b72d022b..59f278532bdc 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -885,6 +885,10 @@ class DrawableRoot implements DrawableParent { bool get hasDrawableContent => children.isNotEmpty == true && !viewport.viewBox.isEmpty; + /// Draws the contents or children of this [Drawable] to the `canvas`, using + /// the `parentPaint` to optionally override the child's paint. + /// + /// The `bounds` is not used. @override void draw(Canvas canvas, Rect bounds) { if (!hasDrawableContent) { From ae4354c89bb8e3809a074931320f8d1a39074522 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Mon, 16 Aug 2021 12:17:12 -0700 Subject: [PATCH 398/512] add a simple scrolling benchmark for the example (#583) * add a simple scrolling benchmark for the example * fix analyzer errors and remove print statements * pub get Co-authored-by: Dan Field --- third_party/example/README.md | 4 +++ third_party/example/pubspec.yaml | 2 ++ third_party/example/test_driver/bench.dart | 7 +++++ .../example/test_driver/bench_test.dart | 27 +++++++++++++++++++ 4 files changed, 40 insertions(+) create mode 100644 third_party/example/test_driver/bench.dart create mode 100644 third_party/example/test_driver/bench_test.dart diff --git a/third_party/example/README.md b/third_party/example/README.md index 64a12f6bc582..5a3229390ff8 100644 --- a/third_party/example/README.md +++ b/third_party/example/README.md @@ -6,3 +6,7 @@ A new Flutter project. For help getting started with Flutter, view our online [documentation](https://flutter.io/). + +## Benchmarking + +`flutter drive --profile --endless-trace-buffer --target test_driver/bench.dart` diff --git a/third_party/example/pubspec.yaml b/third_party/example/pubspec.yaml index c93f4bba8454..57954c786dee 100644 --- a/third_party/example/pubspec.yaml +++ b/third_party/example/pubspec.yaml @@ -6,6 +6,8 @@ publish_to: none dependencies: flutter: sdk: flutter + flutter_driver: + sdk: flutter flutter_svg: path: ../ diff --git a/third_party/example/test_driver/bench.dart b/third_party/example/test_driver/bench.dart new file mode 100644 index 000000000000..7854092ac4a9 --- /dev/null +++ b/third_party/example/test_driver/bench.dart @@ -0,0 +1,7 @@ +import 'package:flutter_driver/driver_extension.dart'; +import 'package:flutter_svg_example/main.dart' as app; + +void main() { + enableFlutterDriverExtension(); + app.main(); +} diff --git a/third_party/example/test_driver/bench_test.dart b/third_party/example/test_driver/bench_test.dart new file mode 100644 index 000000000000..f63172bc7a49 --- /dev/null +++ b/third_party/example/test_driver/bench_test.dart @@ -0,0 +1,27 @@ +import 'package:flutter_driver/flutter_driver.dart'; + +Future main() async { + final SerializableFinder view = find.byType('GridView'); + + final FlutterDriver driver = await FlutterDriver.connect(); + try { + await driver.waitUntilFirstFrameRasterized(); + await Future.delayed(const Duration(milliseconds: 1000)); + await driver.forceGC(); + await driver.clearTimeline(); + await Future.delayed(const Duration(milliseconds: 1000)); + + final Timeline timeline = await driver.traceAction(() async { + await driver.scroll( + view, + 0, -3400, + const Duration(seconds: 10), + timeout: const Duration(seconds: 15), + ); + }); + final TimelineSummary summary = TimelineSummary.summarize(timeline); + await summary.writeTimelineToFile('bench', pretty: true); + } finally { + await driver.close(); + } +} From b1531dd511b37ade9595ce58cceb7415bfbd4f6a Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 16 Aug 2021 12:21:24 -0700 Subject: [PATCH 399/512] ignore avoid_classe_with_only_static_members for now --- .../example/linux/flutter/generated_plugin_registrant.cc | 2 ++ third_party/example/linux/flutter/generated_plugin_registrant.h | 2 ++ .../example/windows/flutter/generated_plugin_registrant.cc | 2 ++ .../example/windows/flutter/generated_plugin_registrant.h | 2 ++ third_party/lib/src/svg/parser_state.dart | 2 ++ 5 files changed, 10 insertions(+) diff --git a/third_party/example/linux/flutter/generated_plugin_registrant.cc b/third_party/example/linux/flutter/generated_plugin_registrant.cc index d38195aa0412..e71a16d23d05 100644 --- a/third_party/example/linux/flutter/generated_plugin_registrant.cc +++ b/third_party/example/linux/flutter/generated_plugin_registrant.cc @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" diff --git a/third_party/example/linux/flutter/generated_plugin_registrant.h b/third_party/example/linux/flutter/generated_plugin_registrant.h index 9bf7478940c1..e0f0a47bc08f 100644 --- a/third_party/example/linux/flutter/generated_plugin_registrant.h +++ b/third_party/example/linux/flutter/generated_plugin_registrant.h @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ diff --git a/third_party/example/windows/flutter/generated_plugin_registrant.cc b/third_party/example/windows/flutter/generated_plugin_registrant.cc index 4bfa0f3a3a75..8b6d4680af38 100644 --- a/third_party/example/windows/flutter/generated_plugin_registrant.cc +++ b/third_party/example/windows/flutter/generated_plugin_registrant.cc @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" diff --git a/third_party/example/windows/flutter/generated_plugin_registrant.h b/third_party/example/windows/flutter/generated_plugin_registrant.h index 9846246b4dac..dc139d85a931 100644 --- a/third_party/example/windows/flutter/generated_plugin_registrant.h +++ b/third_party/example/windows/flutter/generated_plugin_registrant.h @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index 28891752457a..d7aa1f05b437 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -77,6 +77,7 @@ class _TextInfo { String toString() => '$runtimeType{$offset, $style, $transform}'; } +// ignore: avoid_classes_with_only_static_members class _Elements { static Future? svg(SvgParserState parserState, bool warningsAsErrors) { final DrawableViewport? viewBox = parseViewBox(parserState.attributes); @@ -642,6 +643,7 @@ class _Elements { } } +// ignore: avoid_classes_with_only_static_members class _Paths { static Path circle(Map attributes) { final double cx = parseDouble(getAttribute(attributes, 'cx', def: '0'))!; From cafa69ef0718b97d922e7cbf9d15fa733b51ffc9 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 23 Aug 2021 10:55:59 -0700 Subject: [PATCH 400/512] update opacity --- third_party/golden/simple/use_opacity_grid.png | Bin 957 -> 959 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/third_party/golden/simple/use_opacity_grid.png b/third_party/golden/simple/use_opacity_grid.png index 759ee8ea264591a0e63eb92bdb0d9dea951aa7da..e9bd18ccbc1f0e4ecb0fc17a2e280982b604f678 100644 GIT binary patch literal 959 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_tI#PZ!6KiaBp@Z}dve6k-4HIBx?-m(wK;9u00Tv+V47jt9*R-Y29g{@}3l zI&w|vub5RCCr``_FM~I!cYAwWHn|38IU5tH=aD zGS7bb{rBIEINSZ5Kki7${NE?H(ZYV)cBzxkuPxYq^rvI|R%}ySTQtw*9X4<(X!)FXnAeuB^1&wtahdp1P8f)m*=r zn3yAP-{$7z=DIEo(%iMQL!zdAuAlm|=g*UKbJxBoQ&M{L?w#HzoBrRwf3FD9GPJgi zF7aN>u5x-)L~LyBn*RR&$AA9p`7l97R`%%2moJm=W^GNXuit;5kL{s_g+;}h^XJYz z`tV`HhY2RL&t`0m>i_!nYw4A&txVQZEssBa`m}N1u3cTdy}gH=jXtS{ExstR>a$IK z**cE1X~ir4+3C3M+_6Jq)$Y6RHW#~|*p#y(Z~JZ5(oZVqKQG*M{k5%ic*{g)BVOPA zPo6zn_Cjpl%d*|B+dnMIzrRoP?jhs7aqC}*#hDa2y!!epVDE+v0=swbwqLXG`>mTd zJ+Ha`c%SOMGp6tC*|SZ%DmU%3+p|7d>YBpUtkM;FQ@u9s*bxz6?tgDuOkP~}(H_tq4>#f(X`#I0QI@|q)^W3Y%iT7TA zT@C20+E&u<;;@o+AuFX}u zInQM+yZ&$S+-iPWS^Rq&d?cnaC*O3Eemwi$vs2k? zeVM_!R+(&+4k~{7a_7&`UteDqMpgZq7rFQDjP$2M+(IlYlprz_G*Fw}vU*1SUz)G} Sx<~4OO!0K}b6Mw<&;$Si+=Q$E literal 957 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_tJIPZ!6KiaBp@pY>AC6k&VtSi`A%(S#fkwkeG4cY30WdAaU2?qn~2bjbTd zkkSs(P4inbV>C@fzIYk<7`}Dk;GF6DLH%Ei#LFd4zinn;(e!v)acK2@_eepYRb+zw zYgWdszb<|A>SuYuc>UkU>;Fn_++wh)U+UEL({=gY+<*6}HAe2eFOmNB_K9^o`xzJ; zS#YD4nf-e-Pj9lYwCuDwpPZks9~K^7UluPPwEp_zSFg0f!orfOt9QRBQ&L)VGskW5 z#g5&(ci*^mt1D<_NQt-L#s7S>&!*|<=p6a=tLoxg7Z;b^cl&J4FTVZOZDmN;&6_tD zMN8Q!L{2+;>((vj+L{`f=g*(Fwm*6CLc`DBU;fqU)2DCTzpuYxah(MpAD`T-&6_t{ z*x2aUsC?h=@$T-OJ1$FuG(nPjdU|rNUcY{QB zYt-6B(G{V)@9OPp6}Ot}cTsmw){BOa)mIy<3JVR(%FFAcoaMjPoZq;4b8vuq|2+NZ zeKkLYX3w6@TKf6L&w0s0-xQt}RW6t}Z(iThrAwQ3Reo8>zHF0Dchp+3%6aZvqiU=F z8$N4qcz698(2Fk{dOj*H`0ZP@`f8Wg(of(1C7;<`^d4Og#Tav^;h9VtGmaq2mbqW*kJW{>Bno9Rejyx zy?-&A@F^i~p=DM7|5)$Zudsb>NB(_as`w*kXm1Wm72Dtcz4z?-uUcQG%~ksi&t;|M zm@j$uTu0_^e!b+&mnp#1(vhCp$;!#ZL Date: Tue, 14 Sep 2021 17:05:55 -0700 Subject: [PATCH 401/512] Add hacky support for currentColor (#588) * add support for currentColor * refactor to support passing colors down from parent * add another circle to show override works * revert strokeColor change for avd Co-authored-by: Lee Standen --- third_party/example/assets/svg_currentcolor.svg | 7 +++++++ .../linux/flutter/generated_plugin_registrant.cc | 2 -- .../linux/flutter/generated_plugin_registrant.h | 2 -- third_party/example/test_driver/bench_test.dart | 3 ++- .../flutter/generated_plugin_registrant.cc | 2 -- .../flutter/generated_plugin_registrant.h | 2 -- third_party/golden/svg_currentcolor.png | Bin 0 -> 4234 bytes third_party/lib/src/svg/colors.dart | 4 ++++ third_party/lib/src/svg/xml_parsers.dart | 4 +++- third_party/test/colors_svg_test.dart | 2 ++ 10 files changed, 18 insertions(+), 10 deletions(-) create mode 100644 third_party/example/assets/svg_currentcolor.svg create mode 100644 third_party/golden/svg_currentcolor.png diff --git a/third_party/example/assets/svg_currentcolor.svg b/third_party/example/assets/svg_currentcolor.svg new file mode 100644 index 000000000000..850efed2c235 --- /dev/null +++ b/third_party/example/assets/svg_currentcolor.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/third_party/example/linux/flutter/generated_plugin_registrant.cc b/third_party/example/linux/flutter/generated_plugin_registrant.cc index e71a16d23d05..d38195aa0412 100644 --- a/third_party/example/linux/flutter/generated_plugin_registrant.cc +++ b/third_party/example/linux/flutter/generated_plugin_registrant.cc @@ -2,8 +2,6 @@ // Generated file. Do not edit. // -// clang-format off - #include "generated_plugin_registrant.h" diff --git a/third_party/example/linux/flutter/generated_plugin_registrant.h b/third_party/example/linux/flutter/generated_plugin_registrant.h index e0f0a47bc08f..9bf7478940c1 100644 --- a/third_party/example/linux/flutter/generated_plugin_registrant.h +++ b/third_party/example/linux/flutter/generated_plugin_registrant.h @@ -2,8 +2,6 @@ // Generated file. Do not edit. // -// clang-format off - #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ diff --git a/third_party/example/test_driver/bench_test.dart b/third_party/example/test_driver/bench_test.dart index f63172bc7a49..b23125b7fff9 100644 --- a/third_party/example/test_driver/bench_test.dart +++ b/third_party/example/test_driver/bench_test.dart @@ -14,7 +14,8 @@ Future main() async { final Timeline timeline = await driver.traceAction(() async { await driver.scroll( view, - 0, -3400, + 0, + -3400, const Duration(seconds: 10), timeout: const Duration(seconds: 15), ); diff --git a/third_party/example/windows/flutter/generated_plugin_registrant.cc b/third_party/example/windows/flutter/generated_plugin_registrant.cc index 8b6d4680af38..4bfa0f3a3a75 100644 --- a/third_party/example/windows/flutter/generated_plugin_registrant.cc +++ b/third_party/example/windows/flutter/generated_plugin_registrant.cc @@ -2,8 +2,6 @@ // Generated file. Do not edit. // -// clang-format off - #include "generated_plugin_registrant.h" diff --git a/third_party/example/windows/flutter/generated_plugin_registrant.h b/third_party/example/windows/flutter/generated_plugin_registrant.h index dc139d85a931..9846246b4dac 100644 --- a/third_party/example/windows/flutter/generated_plugin_registrant.h +++ b/third_party/example/windows/flutter/generated_plugin_registrant.h @@ -2,8 +2,6 @@ // Generated file. Do not edit. // -// clang-format off - #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ diff --git a/third_party/golden/svg_currentcolor.png b/third_party/golden/svg_currentcolor.png new file mode 100644 index 0000000000000000000000000000000000000000..47d93874deebc2b7ef8c7aec566ac79354514efd GIT binary patch literal 4234 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 literal 0 HcmV?d00001 diff --git a/third_party/lib/src/svg/colors.dart b/third_party/lib/src/svg/colors.dart index 323475c0d5f7..4863e2d18136 100644 --- a/third_party/lib/src/svg/colors.dart +++ b/third_party/lib/src/svg/colors.dart @@ -15,6 +15,10 @@ Color? parseColor(String? colorString) { return null; } + if (colorString.toLowerCase() == 'currentcolor') { + return null; + } + // handle hex colors e.g. #fff or #ffffff. This supports #RRGGBBAA if (colorString[0] == '#') { if (colorString.length == 4) { diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 876ecd369e4b..fff792da7005 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -217,7 +217,8 @@ DrawablePaint? parseStroke( PaintingStyle.stroke, color: rawStroke == '' ? (parentStroke?.color ?? colorBlack).withOpacity(opacity) - : parseColor(rawStroke)!.withOpacity(opacity), + : (parseColor(rawStroke) ?? parentStroke?.color ?? colorBlack) + .withOpacity(opacity), strokeCap: rawStrokeCap == 'null' ? parentStroke?.strokeCap ?? StrokeCap.butt : StrokeCap.values.firstWhere( @@ -267,6 +268,7 @@ DrawablePaint? parseFill( opacity: opacity, ); } + if (rawFill == '' && parentFill == DrawablePaint.empty) { return null; } diff --git a/third_party/test/colors_svg_test.dart b/third_party/test/colors_svg_test.dart index ab02451d0717..45c431ebf2a1 100644 --- a/third_party/test/colors_svg_test.dart +++ b/third_party/test/colors_svg_test.dart @@ -28,6 +28,8 @@ void main() { expect(parseColor('hsl(192,55%,29%)'), const Color(0xFF216273)); expect(parseColor('hsl(297,55%,29%)'), const Color(0xFF6F2173)); expect(parseColor('hsla(0,0%,100%, 0.0)'), const Color(0x00FFFFFF)); + expect(parseColor('currentColor'), null); + expect(parseColor('currentcolor'), null); expect(() => parseColor('invalid name'), throwsStateError); }); } From 07cd7f3670fdbdadc986e3f776411dbf29a96383 Mon Sep 17 00:00:00 2001 From: Bartosz Selwesiuk Date: Sat, 2 Oct 2021 00:15:50 +0200 Subject: [PATCH 402/512] Add support for `currentColor` to `SvgPicture` (#602) --- third_party/lib/avd.dart | 199 ++++++++++++-- third_party/lib/parser.dart | 6 +- third_party/lib/src/picture_provider.dart | 102 +++++-- third_party/lib/src/svg/default_theme.dart | 41 +++ third_party/lib/src/svg/parser_state.dart | 42 ++- third_party/lib/src/svg/theme.dart | 24 ++ third_party/lib/src/svg/xml_parsers.dart | 19 +- third_party/lib/src/vector_drawable.dart | 20 +- third_party/lib/svg.dart | 197 ++++++++------ third_party/pubspec.yaml | 1 + third_party/test/default_theme_test.dart | 79 ++++++ third_party/test/picture_cache_test.dart | 6 +- third_party/test/picture_provider_test.dart | 146 ++++++++++ third_party/test/svg_parsers_test.dart | 285 +++++++++++++++++++- third_party/test/theme_test.dart | 33 +++ third_party/test/vector_drawable_test.dart | 2 + third_party/test/widget_svg_test.dart | 2 + third_party/test/xml_svg_test.dart | 39 +++ third_party/tool/gen_golden.dart | 3 +- 19 files changed, 1115 insertions(+), 131 deletions(-) create mode 100644 third_party/lib/src/svg/default_theme.dart create mode 100644 third_party/lib/src/svg/theme.dart create mode 100644 third_party/test/default_theme_test.dart create mode 100644 third_party/test/picture_provider_test.dart create mode 100644 third_party/test/theme_test.dart diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index 33c88f89a10a..fff441d8d11b 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -2,15 +2,17 @@ import 'dart:convert'; import 'dart:typed_data'; import 'dart:ui' show Picture; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart' show AssetBundle; import 'package:flutter/widgets.dart'; import 'package:xml/xml.dart'; -import './svg.dart'; import 'src/avd/xml_parsers.dart'; import 'src/avd_parser.dart'; import 'src/picture_provider.dart'; import 'src/picture_stream.dart'; +import 'src/render_picture.dart'; +import 'src/unbounded_color_filtered.dart'; import 'src/vector_drawable.dart'; /// Instance for [Avd]'s utility methods, which can produce [DrawableRoot] or @@ -95,24 +97,27 @@ class Avd { /// [PictureProvider]. /// /// Support for AVD is incomplete and experimental at this time. -class AvdPicture extends SvgPicture { - /// Instantiates a widget that renders an SVG picture using the - /// `pictureProvider`. +class AvdPicture extends StatefulWidget { + /// Instantiates a widget that renders an AVD picture using the `pictureProvider`. + /// + /// If `matchTextDirection` is set to true, the picture will be flipped + /// horizontally in [TextDirection.rtl] contexts. + /// + /// The `allowDrawingOutsideOfViewBox` parameter should be used with caution - + /// if set to true, it will not clip the canvas used internally to the view box, + /// meaning the picture may draw beyond the intended area and lead to undefined + /// behavior or additional memory overhead. + /// + /// A custom `placeholderBuilder` can be specified for cases where decoding or + /// acquiring data may take a noticeably long time, e.g. for a network picture. const AvdPicture( - PictureProvider pictureProvider, { + this.pictureProvider, { Key? key, - bool matchTextDirection = false, - bool allowDrawingOutsideViewBox = false, - WidgetBuilder? placeholderBuilder, - ColorFilter? colorFilter, - }) : super( - pictureProvider, - key: key, - matchTextDirection: matchTextDirection, - allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, - placeholderBuilder: placeholderBuilder, - colorFilter: colorFilter, - ); + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + this.colorFilter, + }) : super(key: key); /// Draws an [AvdPicture] from a raw string of XML. AvdPicture.string(String bytes, @@ -125,8 +130,8 @@ class AvdPicture extends SvgPicture { : this( StringPicture( allowDrawingOutsideViewBox == true - ? avdStringDecoderOutsideViewBox - : avdStringDecoder, + ? (_) => avdStringDecoderOutsideViewBox + : (_) => avdStringDecoder, bytes, ), colorFilter: _getColorFilter(color, colorBlendMode), @@ -148,8 +153,8 @@ class AvdPicture extends SvgPicture { : this( ExactAssetPicture( allowDrawingOutsideViewBox == true - ? avdStringDecoderOutsideViewBox - : avdStringDecoder, + ? (_) => avdStringDecoderOutsideViewBox + : (_) => avdStringDecoder, assetName, bundle: bundle, package: package, @@ -160,6 +165,11 @@ class AvdPicture extends SvgPicture { placeholderBuilder: placeholderBuilder, key: key); + /// The default placeholder for an AVD that may take time to parse or + /// retrieve, e.g. from a network location. + static WidgetBuilder defaultPlaceholderBuilder = + (BuildContext ctx) => const LimitedBox(); + static ColorFilter? _getColorFilter(Color? color, BlendMode colorBlendMode) => color == null ? null : ColorFilter.mode(color, colorBlendMode); @@ -182,4 +192,151 @@ class AvdPicture extends SvgPicture { static final PictureInfoDecoder avdStringDecoderOutsideViewBox = (String data, ColorFilter? colorFilter, String key) => avd.avdPictureStringDecoder(data, true, colorFilter, key); + + /// The [PictureProvider] used to resolve the AVD. + final PictureProvider pictureProvider; + + /// The placeholder to use while fetching, decoding, and parsing the AVD data. + final WidgetBuilder? placeholderBuilder; + + /// If true, will horizontally flip the picture in [TextDirection.rtl] contexts. + final bool matchTextDirection; + + /// If true, will allow the AVD to be drawn outside of the clip boundary of its + /// viewBox. + final bool allowDrawingOutsideViewBox; + + /// The color filter, if any, to apply to this widget. + final ColorFilter? colorFilter; + + @override + State createState() => _AvdPictureState(); +} + +class _AvdPictureState extends State { + PictureInfo? _picture; + PictureStream? _pictureStream; + bool _isListeningToStream = false; + + @override + void didChangeDependencies() { + _resolveImage(); + + if (TickerMode.of(context)) { + _listenToStream(); + } else { + _stopListeningToStream(); + } + super.didChangeDependencies(); + } + + @override + void didUpdateWidget(AvdPicture oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.pictureProvider != oldWidget.pictureProvider) { + _resolveImage(); + } + } + + @override + void reassemble() { + _resolveImage(); // in case the image cache was flushed + super.reassemble(); + } + + void _resolveImage() { + final PictureStream newStream = widget.pictureProvider + .resolve(createLocalPictureConfiguration(context)); + assert(newStream != null); // ignore: unnecessary_null_comparison + _updateSourceStream(newStream); + } + + void _handleImageChanged(PictureInfo? imageInfo, bool synchronousCall) { + setState(() { + _picture = imageInfo; + }); + } + + // Update _pictureStream to newStream, and moves the stream listener + // registration from the old stream to the new stream (if a listener was + // registered). + void _updateSourceStream(PictureStream newStream) { + if (_pictureStream?.key == newStream.key) { + return; + } + + if (_isListeningToStream) + _pictureStream!.removeListener(_handleImageChanged); + + _pictureStream = newStream; + if (_isListeningToStream) { + _pictureStream!.addListener(_handleImageChanged); + } + } + + void _listenToStream() { + if (_isListeningToStream) { + return; + } + _pictureStream!.addListener(_handleImageChanged); + _isListeningToStream = true; + } + + void _stopListeningToStream() { + if (!_isListeningToStream) { + return; + } + _pictureStream!.removeListener(_handleImageChanged); + _isListeningToStream = false; + } + + @override + void dispose() { + assert(_pictureStream != null); + _stopListeningToStream(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + late Widget child; + if (_picture != null) { + final Rect viewport = Offset.zero & _picture!.viewport.size; + + child = SizedBox( + width: viewport.width, + height: viewport.height, + child: FittedBox( + clipBehavior: Clip.hardEdge, + child: SizedBox.fromSize( + size: viewport.size, + child: RawPicture( + _picture, + matchTextDirection: widget.matchTextDirection, + allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, + ), + ), + ), + ); + + if (widget.pictureProvider.colorFilter == null && + widget.colorFilter != null) { + child = UnboundedColorFiltered( + colorFilter: widget.colorFilter, + child: child, + ); + } + } else { + child = AvdPicture.defaultPlaceholderBuilder(context); + } + return child; + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder description) { + super.debugFillProperties(description); + description.add( + DiagnosticsProperty('stream', _pictureStream), + ); + } } diff --git a/third_party/lib/parser.dart b/third_party/lib/parser.dart index 22cd1fdf4849..d720192f79f5 100644 --- a/third_party/lib/parser.dart +++ b/third_party/lib/parser.dart @@ -1,11 +1,12 @@ import 'package:xml/xml_events.dart' as xml show parseEvents; import 'src/svg/parser_state.dart'; +import 'src/svg/theme.dart'; import 'src/vector_drawable.dart'; /// Parses SVG data into a [DrawableRoot]. class SvgParser { - /// Parses SVG from a string to a [DrawableRoot]. + /// Parses SVG from a string to a [DrawableRoot] with the provided [theme]. /// /// The [key] parameter is used for debugging purposes. /// @@ -17,11 +18,12 @@ class SvgParser { /// Defaults to false. Future parse( String str, { + SvgTheme? theme, String? key, bool warningsAsErrors = false, }) async { final SvgParserState state = - SvgParserState(xml.parseEvents(str), key, warningsAsErrors); + SvgParserState(xml.parseEvents(str), theme, key, warningsAsErrors); return await state.parse(); } } diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 926e91c9763a..503d6c3f2080 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -27,6 +27,12 @@ typedef PictureInfoDecoder = Future Function( String key, ); +/// The signature of a builder that returns a [PictureInfoDecoder] +/// based on the [currentColor]. +typedef PictureInfoDecoderBuilder = PictureInfoDecoder Function( + Color? currentColor, +); + /// Creates an [PictureConfiguration] based on the given [BuildContext] (and /// optionally size). /// @@ -299,7 +305,7 @@ class PictureConfiguration { abstract class PictureProvider { /// Abstract const constructor. This constructor enables subclasses to provide /// const constructors so that they can be used in const expressions. - const PictureProvider(this.colorFilter); + PictureProvider(this.colorFilter); /// The [PictureCache] for [Picture] objects created by [PictureProvider] /// implementations. @@ -316,6 +322,14 @@ abstract class PictureProvider { /// The color filter to apply to the picture, if any. final ColorFilter? colorFilter; + /// The default color applied to SVG elements that inherit the color property. + @visibleForTesting + Color? get currentColor => _currentColor; + Color? _currentColor; + + /// Sets the [_currentColor] to [color]. + set currentColor(Color? color); + /// Resolves this Picture provider using the given `configuration`, returning /// an [PictureStream]. /// @@ -433,12 +447,23 @@ abstract class AssetBundlePictureProvider extends PictureProvider { /// Abstract const constructor. This constructor enables subclasses to provide /// const constructors so that they can be used in const expressions. - const AssetBundlePictureProvider(this.decoder, ColorFilter? colorFilter) - : assert(decoder != null), // ignore: unnecessary_null_comparison + AssetBundlePictureProvider(this.decoderBuilder, ColorFilter? colorFilter) + : assert(decoderBuilder != null), // ignore: unnecessary_null_comparison + decoder = decoderBuilder(null), super(colorFilter); + /// The decoder builder to build a [decoder] when [currentColor] changes. + final PictureInfoDecoderBuilder decoderBuilder; + /// The decoder to use to turn a string into a [PictureInfo] object. - final PictureInfoDecoder decoder; + @visibleForTesting + PictureInfoDecoder decoder; + + @override + set currentColor(Color? color) { + _currentColor = color; + decoder = decoderBuilder(_currentColor); + } /// Converts a key into an [PictureStreamCompleter], and begins fetching the /// picture using [_loadAsync]. @@ -488,13 +513,18 @@ class NetworkPicture extends PictureProvider { /// Creates an object that fetches the picture at the given URL. /// /// The arguments must not be null. - const NetworkPicture(this.decoder, this.url, + NetworkPicture(this.decoderBuilder, this.url, {this.headers, ColorFilter? colorFilter}) : assert(url != null), // ignore: unnecessary_null_comparison + decoder = decoderBuilder(null), super(colorFilter); + /// The decoder builder to build a [decoder] when [currentColor] changes. + final PictureInfoDecoderBuilder decoderBuilder; + /// The decoder to use to turn a [Uint8List] into a [PictureInfo] object. - final PictureInfoDecoder decoder; + @visibleForTesting + PictureInfoDecoder decoder; /// The URL from which the picture will be fetched. final String url; @@ -502,6 +532,12 @@ class NetworkPicture extends PictureProvider { /// The HTTP headers that will be used with [HttpClient.get] to fetch picture from network. final Map? headers; + @override + set currentColor(Color? color) { + _currentColor = color; + decoder = decoderBuilder(_currentColor); + } + @override Future obtainKey(PictureConfiguration picture) { return SynchronousFuture(this); @@ -521,6 +557,7 @@ class NetworkPicture extends PictureProvider { {PictureErrorListener? onError}) async { assert(key == this); final Uint8List bytes = await httpGet(url, headers: headers); + if (onError != null) { return decoder( bytes, @@ -562,16 +599,27 @@ class FilePicture extends PictureProvider { /// Creates an object that decodes a [File] as a picture. /// /// The arguments must not be null. - const FilePicture(this.decoder, this.file, {ColorFilter? colorFilter}) - : assert(decoder != null), // ignore: unnecessary_null_comparison + FilePicture(this.decoderBuilder, this.file, {ColorFilter? colorFilter}) + : assert(decoderBuilder != null), // ignore: unnecessary_null_comparison assert(file != null), // ignore: unnecessary_null_comparison + decoder = decoderBuilder(null), super(colorFilter); /// The file to decode into a picture. final File file; + /// The decoder builder to build a [decoder] when [currentColor] changes. + final PictureInfoDecoderBuilder decoderBuilder; + /// The [PictureInfoDecoder] to use for loading this picture. - final PictureInfoDecoder decoder; + @visibleForTesting + PictureInfoDecoder decoder; + + @override + set currentColor(Color? color) { + _currentColor = color; + decoder = decoderBuilder(_currentColor); + } @override Future obtainKey(PictureConfiguration picture) { @@ -642,16 +690,27 @@ class MemoryPicture extends PictureProvider { /// Creates an object that decodes a [Uint8List] buffer as a picture. /// /// The arguments must not be null. - const MemoryPicture(this.decoder, this.bytes, {ColorFilter? colorFilter}) + MemoryPicture(this.decoderBuilder, this.bytes, {ColorFilter? colorFilter}) : assert(bytes != null), // ignore: unnecessary_null_comparison + decoder = decoderBuilder(null), super(colorFilter); + /// The decoder builder to build a [decoder] when [currentColor] changes. + final PictureInfoDecoderBuilder decoderBuilder; + /// The [PictureInfoDecoder] to use when drawing this picture. - final PictureInfoDecoder decoder; + @visibleForTesting + PictureInfoDecoder decoder; /// The bytes to decode into a picture. final Uint8List bytes; + @override + set currentColor(Color? color) { + _currentColor = color; + decoder = decoderBuilder(_currentColor); + } + @override Future obtainKey(PictureConfiguration picture) { return SynchronousFuture(this); @@ -712,16 +771,27 @@ class StringPicture extends PictureProvider { /// Creates an object that decodes a [Uint8List] buffer as a picture. /// /// The arguments must not be null. - const StringPicture(this.decoder, this.string, {ColorFilter? colorFilter}) + StringPicture(this.decoderBuilder, this.string, {ColorFilter? colorFilter}) : assert(string != null), // ignore: unnecessary_null_comparison + decoder = decoderBuilder(null), super(colorFilter); + /// The decoder builder to build a [decoder] when [currentColor] changes. + final PictureInfoDecoderBuilder decoderBuilder; + /// The [PictureInfoDecoder] to use for decoding this picture. - final PictureInfoDecoder decoder; + @visibleForTesting + PictureInfoDecoder decoder; /// The string to decode into a picture. final String string; + @override + set currentColor(Color? color) { + _currentColor = color; + decoder = decoderBuilder(_currentColor); + } + @override Future obtainKey(PictureConfiguration picture) { return SynchronousFuture(this); @@ -850,14 +920,14 @@ class ExactAssetPicture extends AssetBundlePictureProvider { /// The [package] argument must be non-null when fetching an asset that is /// included in a package. See the documentation for the [ExactAssetPicture] class /// itself for details. - const ExactAssetPicture( - PictureInfoDecoder decoder, + ExactAssetPicture( + PictureInfoDecoderBuilder decoderBuilder, this.assetName, { this.bundle, this.package, ColorFilter? colorFilter, }) : assert(assetName != null), // ignore: unnecessary_null_comparison - super(decoder, colorFilter); + super(decoderBuilder, colorFilter); /// The name of the asset. final String assetName; diff --git a/third_party/lib/src/svg/default_theme.dart b/third_party/lib/src/svg/default_theme.dart new file mode 100644 index 000000000000..e85cca7e271f --- /dev/null +++ b/third_party/lib/src/svg/default_theme.dart @@ -0,0 +1,41 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/src/svg/theme.dart'; + +/// The SVG theme to apply to descendant [SvgPicture] widgets +/// which don't have explicit theme values. +class DefaultSvgTheme extends InheritedTheme { + /// Creates a default SVG theme for the given subtree + /// using the provided [theme]. + const DefaultSvgTheme({ + Key? key, + required Widget child, + required this.theme, + }) : super(key: key, child: child); + + /// The SVG theme to apply. + final SvgTheme theme; + + /// The closest instance of this class that encloses the given context. + /// + /// Typical usage is as follows: + /// + /// ```dart + /// DefaultSvgTheme theme = DefaultSvgTheme.of(context); + /// ``` + static DefaultSvgTheme? of(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType(); + } + + @override + bool updateShouldNotify(DefaultSvgTheme oldWidget) { + return theme != oldWidget.theme; + } + + @override + Widget wrap(BuildContext context, Widget child) { + return DefaultSvgTheme( + theme: theme, + child: child, + ); + } +} diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index d7aa1f05b437..a2514352dff4 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -6,6 +6,7 @@ import 'package:path_drawing/path_drawing.dart'; import 'package:vector_math/vector_math_64.dart'; import 'package:xml/xml_events.dart' hide parseEvents; +import '../svg/theme.dart'; import '../utilities/errors.dart'; import '../utilities/numbers.dart'; import '../utilities/xml.dart'; @@ -83,6 +84,12 @@ class _Elements { final DrawableViewport? viewBox = parseViewBox(parserState.attributes); final String? id = parserState.attribute('id', def: ''); + final Color? color = + parseColor(parserState.attribute('color', def: null)) ?? + // Fallback to the currentColor from theme if no color is defined + // on the root SVG element. + parserState.theme?.currentColor; + // TODO(dnfield): Support nested SVG elements. https://github.com/dnfield/flutter_svg/issues/132 if (parserState._root != null) { const String errorMessage = 'Unsupported nested element.'; @@ -102,6 +109,7 @@ class _Elements { library: 'SVG', context: ErrorDescription('in _Element.svg'), )); + parserState._parentDrawables.addLast( _SvgGroupTuple( 'svg', @@ -114,7 +122,9 @@ class _Elements { parserState._definitions, viewBox!.viewBoxRect, null, + currentColor: color, ), + color: color, ), ), ); @@ -131,7 +141,9 @@ class _Elements { parserState._definitions, viewBox.viewBoxRect, null, + currentColor: color, ), + color: color, ); parserState.addGroup(parserState._currentStartElement!, parserState._root); return null; @@ -139,6 +151,9 @@ class _Elements { static Future? g(SvgParserState parserState, bool warningsAsErrors) { final DrawableParent parent = parserState.currentGroup!; + final Color? color = + parseColor(parserState.attribute('color', def: null)) ?? parent.color; + final DrawableGroup group = DrawableGroup( parserState.attribute('id', def: ''), [], @@ -148,8 +163,10 @@ class _Elements { parserState._definitions, parserState.rootBounds, parent.style, + currentColor: color, ), transform: parseTransform(parserState.attribute('transform'))?.storage, + color: color, ); if (!parserState._inDefs) { parent.children!.add(group); @@ -161,6 +178,9 @@ class _Elements { static Future? symbol( SvgParserState parserState, bool warningsAsErrors) { final DrawableParent parent = parserState.currentGroup!; + final Color? color = + parseColor(parserState.attribute('color', def: null)) ?? parent.color; + final DrawableGroup group = DrawableGroup( parserState.attribute('id', def: ''), [], @@ -170,8 +190,10 @@ class _Elements { parserState._definitions, null, parent.style, + currentColor: color, ), transform: parseTransform(parserState.attribute('transform'))?.storage, + color: color, ); parserState.addGroup(parserState._currentStartElement!, group); return null; @@ -190,6 +212,7 @@ class _Elements { parserState._definitions, parserState.rootBounds, parent!.style, + currentColor: parent.color, ); final Matrix4 transform = @@ -221,6 +244,8 @@ class _Elements { List colors, List offsets, ) { + final DrawableParent parent = parserState.currentGroup!; + for (XmlEvent event in parserState._readSubtree()) { if (event is XmlEndElementEvent) { continue; @@ -233,6 +258,7 @@ class _Elements { ); final Color stopColor = parseColor(getAttribute(parserState.attributes, 'stop-color')) ?? + parent.color ?? colorBlack; colors.add(stopColor.withOpacity(parseDouble(rawOpacity)!)); @@ -529,6 +555,7 @@ class _Elements { parserState._definitions, parserState.rootBounds, parentStyle, + currentColor: parent.color, ), size: size, transform: parseTransform(parserState.attribute('transform'))?.storage, @@ -731,11 +758,19 @@ class _SvgGroupTuple { /// Maintains state while pushing an [XmlPushReader] through the SVG tree. class SvgParserState { /// Creates a new [SvgParserState]. - SvgParserState(Iterable events, this._key, this._warningsAsErrors) - // ignore: unnecessary_null_comparison - : assert(events != null), + SvgParserState( + Iterable events, + this.theme, + this._key, + this._warningsAsErrors, + ) + // ignore: unnecessary_null_comparison + : assert(events != null), _eventIterator = events.iterator; + /// A theme used when parsing SVG elements. + final SvgTheme? theme; + final Iterator _eventIterator; final String? _key; final bool _warningsAsErrors; @@ -893,6 +928,7 @@ class SvgParserState { path.getBounds(), parentStyle, defaultFillColor: colorBlack, + currentColor: parent.color, ), transform: parseTransform(getAttribute(attributes, 'transform'))?.storage, ); diff --git a/third_party/lib/src/svg/theme.dart b/third_party/lib/src/svg/theme.dart new file mode 100644 index 000000000000..ed2060055b98 --- /dev/null +++ b/third_party/lib/src/svg/theme.dart @@ -0,0 +1,24 @@ +import 'dart:ui'; + +/// A theme used when decoding an SVG picture. +class SvgTheme { + /// Instantiates an SVG theme with the [currentColor]. + const SvgTheme({ + this.currentColor, + }); + + /// The default color applied to SVG elements that inherit the color property. + /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword + final Color? currentColor; + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + return other is SvgTheme && currentColor == other.currentColor; + } + + @override + int get hashCode => currentColor.hashCode; +} diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index fff792da7005..d46d987ba676 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -178,6 +178,7 @@ DrawablePaint? parseStroke( Rect? bounds, DrawableDefinitionServer definitions, DrawablePaint? parentStroke, + Color? currentColor, ) { final String rawStroke = getAttribute(attributes, 'stroke')!; final String? rawStrokeOpacity = getAttribute( @@ -217,7 +218,10 @@ DrawablePaint? parseStroke( PaintingStyle.stroke, color: rawStroke == '' ? (parentStroke?.color ?? colorBlack).withOpacity(opacity) - : (parseColor(rawStroke) ?? parentStroke?.color ?? colorBlack) + : (parseColor(rawStroke) ?? + currentColor ?? + parentStroke?.color ?? + colorBlack) .withOpacity(opacity), strokeCap: rawStrokeCap == 'null' ? parentStroke?.strokeCap ?? StrokeCap.butt @@ -249,6 +253,7 @@ DrawablePaint? parseFill( DrawableDefinitionServer definitions, DrawablePaint? parentFill, Color? defaultFillColor, + Color? currentColor, ) { final String rawFill = getAttribute(el, 'fill')!; final String? rawFillOpacity = getAttribute(el, 'fill-opacity', def: '1.0'); @@ -284,6 +289,7 @@ DrawablePaint? parseFill( opacity, rawOpacity != '' || rawFillOpacity != '', defaultFillColor, + currentColor, ), ); } @@ -294,9 +300,13 @@ Color? _determineFillColor( double opacity, bool explicitOpacity, Color? defaultFillColor, + Color? currentColor, ) { - final Color? color = - parseColor(rawFill) ?? parentFillColor ?? defaultFillColor; + final Color? color = parseColor(rawFill) ?? + currentColor ?? + parentFillColor ?? + defaultFillColor; + if (explicitOpacity && color != null) { return color.withOpacity(opacity); } @@ -465,6 +475,7 @@ DrawableStyle parseStyle( Rect? bounds, DrawableStyle? parentStyle, { Color? defaultFillColor, + Color? currentColor, }) { return DrawableStyle.mergeAndBlend( parentStyle, @@ -474,6 +485,7 @@ DrawableStyle parseStyle( bounds, definitions, parentStyle?.stroke, + currentColor, ), dashArray: parseDashArray(attributes), dashOffset: parseDashOffset(attributes), @@ -484,6 +496,7 @@ DrawableStyle parseStyle( definitions, parentStyle?.fill, defaultFillColor, + currentColor, ), pathFillType: parseFillRule( attributes, diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 59f278532bdc..bb9faf747ee4 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -55,6 +55,12 @@ abstract class DrawableParent implements DrawableStyleable { /// /// Each child may itself have children. List? get children; + + /// The default color used to provide a potential indirect color value + /// for the `fill`, `stroke` and `stop-color` of descendant elements. + /// + /// See: https://www.w3.org/TR/SVG11/color.html#ColorProperty + Color? get color; } /// Styling information for vector drawing. @@ -840,6 +846,7 @@ class DrawableRoot implements DrawableParent { this.definitions, this.style, { this.transform, + this.color, }); /// The expected coordinates used by child paths for drawing. @@ -851,6 +858,9 @@ class DrawableRoot implements DrawableParent { @override final Float64List? transform; + @override + final Color? color; + @override final List children; @@ -986,7 +996,13 @@ class DrawableRoot implements DrawableParent { /// `stroke`, or `fill`. class DrawableGroup implements DrawableStyleable, DrawableParent { /// Creates a new DrawableGroup. - const DrawableGroup(this.id, this.children, this.style, {this.transform}); + const DrawableGroup( + this.id, + this.children, + this.style, { + this.transform, + this.color, + }); @override final String? id; @@ -997,6 +1013,8 @@ class DrawableGroup implements DrawableStyleable, DrawableParent { final DrawableStyle? style; @override final Float64List? transform; + @override + final Color? color; @override bool get hasDrawableContent => children != null && children!.isNotEmpty; diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 7a7faca4d76d..bbc51d9cc4a8 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -8,11 +8,13 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart' show AssetBundle; import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/src/svg/default_theme.dart'; import 'parser.dart'; import 'src/picture_provider.dart'; import 'src/picture_stream.dart'; import 'src/render_picture.dart'; +import 'src/svg/theme.dart'; import 'src/unbounded_color_filtered.dart'; import 'src/vector_drawable.dart'; @@ -48,9 +50,10 @@ class Svg { Uint8List raw, bool allowDrawingOutsideOfViewBox, ColorFilter? colorFilter, + SvgTheme theme, String key, ) async { - final DrawableRoot svgRoot = await fromSvgBytes(raw, key); + final DrawableRoot svgRoot = await fromSvgBytes(raw, theme, key); final Picture pic = svgRoot.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter, @@ -73,11 +76,13 @@ class Svg { /// /// The [key] will be used for debugging purposes. Future svgPictureStringDecoder( - String raw, - bool allowDrawingOutsideOfViewBox, - ColorFilter? colorFilter, - String key) async { - final DrawableRoot svg = await fromSvgString(raw, key); + String raw, + bool allowDrawingOutsideOfViewBox, + ColorFilter? colorFilter, + SvgTheme theme, + String key, + ) async { + final DrawableRoot svg = await fromSvgString(raw, theme, key); return PictureInfo( picture: svg.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, @@ -93,13 +98,17 @@ class Svg { /// UTF8 encoding). /// /// The `key` will be used for debugging purposes. - Future fromSvgBytes(Uint8List raw, String key) async { + Future fromSvgBytes( + Uint8List raw, + SvgTheme theme, + String key, + ) async { // TODO(dnfield): do utf decoding in another thread? // Might just have to live with potentially slow(ish) decoding, this is causing errors. // See: https://github.com/dart-lang/sdk/issues/31954 // See: https://github.com/flutter/flutter/blob/bf3bd7667f07709d0b817ebfcb6972782cfef637/packages/flutter/lib/src/services/asset_bundle.dart#L66 // if (raw.lengthInBytes < 20 * 1024) { - return fromSvgString(utf8.decode(raw), key); + return fromSvgString(utf8.decode(raw), theme, key); // } else { // final String str = // await compute(_utf8Decode, raw, debugLabel: 'UTF8 decode for SVG'); @@ -114,9 +123,13 @@ class Svg { /// Creates a [DrawableRoot] from a string of SVG data. /// /// The `key` is used for debugging purposes. - Future fromSvgString(String rawSvg, String key) async { + Future fromSvgString( + String rawSvg, + SvgTheme theme, + String key, + ) async { final SvgParser parser = SvgParser(); - return await parser.parse(rawSvg, key: key); + return await parser.parse(rawSvg, theme: theme, key: key); } } @@ -186,45 +199,6 @@ Future precachePicture( /// filtering used into the key (meaning the same SVG with two different `color` /// arguments applied would be two cache entries). class SvgPicture extends StatefulWidget { - /// Instantiates a widget that renders an SVG picture using the `pictureProvider`. - /// - /// Either the [width] and [height] arguments should be specified, or the - /// widget should be placed in a context that sets tight layout constraints. - /// Otherwise, the image dimensions will change as the image is loaded, which - /// will result in ugly layout changes. - /// - /// If `matchTextDirection` is set to true, the picture will be flipped - /// horizontally in [TextDirection.rtl] contexts. - /// - /// The `allowDrawingOutsideOfViewBox` parameter should be used with caution - - /// if set to true, it will not clip the canvas used internally to the view box, - /// meaning the picture may draw beyond the intended area and lead to undefined - /// behavior or additional memory overhead. - /// - /// A custom `placeholderBuilder` can be specified for cases where decoding or - /// acquiring data may take a noticeably long time, e.g. for a network picture. - /// - /// The `semanticsLabel` can be used to identify the purpose of this picture for - /// screen reading software. - /// - /// If [excludeFromSemantics] is true, then [semanticLabel] will be ignored. - const SvgPicture( - this.pictureProvider, { - Key? key, - this.width, - this.height, - this.fit = BoxFit.contain, - this.alignment = Alignment.center, - this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder, - this.semanticsLabel, - this.excludeFromSemantics = false, - this.clipBehavior = Clip.hardEdge, - this.colorFilter, - this.cacheColorFilter = false, - }) : super(key: key); - /// Instantiates a widget that renders an SVG picture from an [AssetBundle]. /// /// The key will be derived from the `assetName`, `package`, and `bundle` @@ -251,6 +225,9 @@ class SvgPicture extends StatefulWidget { /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. /// + /// The `currentColor` argument, if provided, will override the default color + /// of any SVG element that inherits its color. + /// /// ## Assets in packages /// /// To create the widget with an asset from a package, the [package] argument @@ -320,10 +297,11 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, + this.currentColor, }) : pictureProvider = ExactAssetPicture( allowDrawingOutsideViewBox == true - ? svgStringDecoderOutsideViewBox - : svgStringDecoder, + ? svgStringDecoderOutsideViewBoxBuilder + : svgStringDecoderBuilder, assetName, bundle: bundle, package: package, @@ -357,6 +335,9 @@ class SvgPicture extends StatefulWidget { /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. /// + /// The `currentColor` argument, if provided, will override the default color + /// of any SVG element that inherits its color. + /// /// All network images are cached regardless of HTTP headers. /// /// An optional `headers` argument can be used to send custom HTTP headers @@ -380,10 +361,11 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, + this.currentColor, }) : pictureProvider = NetworkPicture( allowDrawingOutsideViewBox == true - ? svgByteDecoderOutsideViewBox - : svgByteDecoder, + ? svgByteDecoderOutsideViewBoxBuilder + : svgByteDecoderBuilder, url, headers: headers, colorFilter: svg.cacheColorFilterOverride ?? cacheColorFilter @@ -416,6 +398,9 @@ class SvgPicture extends StatefulWidget { /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. /// + /// The `currentColor` argument, if provided, will override the default color + /// of any SVG element that inherits its color. + /// /// On Android, this may require the /// `android.permission.READ_EXTERNAL_STORAGE` permission. /// @@ -436,10 +421,11 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, + this.currentColor, }) : pictureProvider = FilePicture( allowDrawingOutsideViewBox == true - ? svgByteDecoderOutsideViewBox - : svgByteDecoder, + ? svgByteDecoderOutsideViewBoxBuilder + : svgByteDecoderBuilder, file, colorFilter: svg.cacheColorFilterOverride ?? cacheColorFilter ? _getColorFilter(color, colorBlendMode) @@ -471,6 +457,9 @@ class SvgPicture extends StatefulWidget { /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. /// + /// The `currentColor` argument, if provided, will override the default color + /// of any SVG element that inherits its color. + /// /// If [excludeFromSemantics] is true, then [semanticLabel] will be ignored. SvgPicture.memory( Uint8List bytes, { @@ -488,10 +477,11 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, + this.currentColor, }) : pictureProvider = MemoryPicture( allowDrawingOutsideViewBox == true - ? svgByteDecoderOutsideViewBox - : svgByteDecoder, + ? svgByteDecoderOutsideViewBoxBuilder + : svgByteDecoderBuilder, bytes, colorFilter: svg.cacheColorFilterOverride ?? cacheColorFilter ? _getColorFilter(color, colorBlendMode) @@ -523,9 +513,12 @@ class SvgPicture extends StatefulWidget { /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. /// + /// The `currentColor` argument, if provided, will override the default color + /// of any SVG element that inherits its color. + /// /// If [excludeFromSemantics] is true, then [semanticLabel] will be ignored. SvgPicture.string( - String bytes, { + String string, { Key? key, this.width, this.height, @@ -540,11 +533,12 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, + this.currentColor, }) : pictureProvider = StringPicture( allowDrawingOutsideViewBox == true - ? svgStringDecoderOutsideViewBox - : svgStringDecoder, - bytes, + ? svgStringDecoderOutsideViewBoxBuilder + : svgStringDecoderBuilder, + string, colorFilter: svg.cacheColorFilterOverride ?? cacheColorFilter ? _getColorFilter(color, colorBlendMode) : null, @@ -560,25 +554,53 @@ class SvgPicture extends StatefulWidget { static ColorFilter? _getColorFilter(Color? color, BlendMode colorBlendMode) => color == null ? null : ColorFilter.mode(color, colorBlendMode); - /// A [PictureInfoDecoder] for [Uint8List]s that will clip to the viewBox. - static final PictureInfoDecoder svgByteDecoder = - (Uint8List bytes, ColorFilter? colorFilter, String key) => - svg.svgPictureDecoder(bytes, false, colorFilter, key); - - /// A [PictureInfoDecoder] for strings that will clip to the viewBox. - static final PictureInfoDecoder svgStringDecoder = - (String data, ColorFilter? colorFilter, String key) => - svg.svgPictureStringDecoder(data, false, colorFilter, key); - - /// A [PictureInfoDecoder] for [Uint8List]s that will not clip to the viewBox. - static final PictureInfoDecoder svgByteDecoderOutsideViewBox = - (Uint8List bytes, ColorFilter? colorFilter, String key) => - svg.svgPictureDecoder(bytes, true, colorFilter, key); - - /// A [PictureInfoDecoder] for [String]s that will not clip to the viewBox. - static final PictureInfoDecoder svgStringDecoderOutsideViewBox = - (String data, ColorFilter? colorFilter, String key) => - svg.svgPictureStringDecoder(data, true, colorFilter, key); + /// A [PictureInfoDecoderBuilder] for [Uint8List]s that will clip to the viewBox. + static final PictureInfoDecoderBuilder svgByteDecoderBuilder = + (Color? currentColor) => + (Uint8List bytes, ColorFilter? colorFilter, String key) => + svg.svgPictureDecoder( + bytes, + false, + colorFilter, + SvgTheme(currentColor: currentColor), + key, + ); + + /// A [PictureInfoDecoderBuilder] for strings that will clip to the viewBox. + static final PictureInfoDecoderBuilder svgStringDecoderBuilder = + (Color? currentColor) => + (String data, ColorFilter? colorFilter, String key) => + svg.svgPictureStringDecoder( + data, + false, + colorFilter, + SvgTheme(currentColor: currentColor), + key, + ); + + /// A [PictureInfoDecoderBuilder] for [Uint8List]s that will not clip to the viewBox. + static final PictureInfoDecoderBuilder + svgByteDecoderOutsideViewBoxBuilder = (Color? currentColor) => + (Uint8List bytes, ColorFilter? colorFilter, String key) => + svg.svgPictureDecoder( + bytes, + true, + colorFilter, + SvgTheme(currentColor: currentColor), + key, + ); + + /// A [PictureInfoDecoderBuilder] for [String]s that will not clip to the viewBox. + static final PictureInfoDecoderBuilder + svgStringDecoderOutsideViewBoxBuilder = (Color? currentColor) => + (String data, ColorFilter? colorFilter, String key) => + svg.svgPictureStringDecoder( + data, + true, + colorFilter, + SvgTheme(currentColor: currentColor), + key, + ); /// If specified, the width to use for the SVG. If unspecified, the SVG /// will take the width of its parent. @@ -664,6 +686,10 @@ class SvgPicture extends StatefulWidget { /// This defaults to false and must not be null. final bool cacheColorFilter; + /// The default color applied to SVG elements that inherit the color property. + /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword + final Color? currentColor; + @override State createState() => _SvgPictureState(); } @@ -675,6 +701,7 @@ class _SvgPictureState extends State { @override void didChangeDependencies() { + _updatePictureProvider(); _resolveImage(); if (TickerMode.of(context)) { @@ -689,16 +716,26 @@ class _SvgPictureState extends State { void didUpdateWidget(SvgPicture oldWidget) { super.didUpdateWidget(oldWidget); if (widget.pictureProvider != oldWidget.pictureProvider) { + _updatePictureProvider(); _resolveImage(); } } @override void reassemble() { + _updatePictureProvider(); _resolveImage(); // in case the image cache was flushed super.reassemble(); } + /// Updates the `currentColor` of the picture provider based on either + /// the widget's `currentColor` property or [DefaultSvgTheme]. + void _updatePictureProvider() { + final SvgTheme? svgTheme = DefaultSvgTheme.of(context)?.theme; + final Color? currentColor = widget.currentColor ?? svgTheme?.currentColor; + widget.pictureProvider.currentColor = currentColor; + } + void _resolveImage() { final PictureStream newStream = widget.pictureProvider .resolve(createLocalPictureConfiguration(context)); diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 153f7a90bde1..87ac0858a344 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -15,6 +15,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + mocktail: ^0.1.4 path: ^1.8.0 test: ^1.16.0 diff --git a/third_party/test/default_theme_test.dart b/third_party/test/default_theme_test.dart new file mode 100644 index 000000000000..b5cd4fc67ff8 --- /dev/null +++ b/third_party/test/default_theme_test.dart @@ -0,0 +1,79 @@ +// ignore_for_file: prefer_const_constructors + +import 'dart:ui'; + +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_svg/src/svg/default_theme.dart'; +import 'package:flutter_svg/src/svg/theme.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('DefaultSvgTheme', () { + testWidgets('changes propagate to SvgPicture', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + currentColor: Color(0xFF733821), + ); + + final SvgPicture svgPictureWidget = SvgPicture.string(''' + + +'''); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + + SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + svgPicture.pictureProvider.currentColor, + equals(svgTheme.currentColor), + ); + + const SvgTheme anotherSvgTheme = SvgTheme( + currentColor: Color(0xFF05290E), + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: anotherSvgTheme, + child: svgPictureWidget, + )); + + svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + svgPicture.pictureProvider.currentColor, + equals(anotherSvgTheme.currentColor), + ); + }); + + testWidgets( + 'currentColor widget property takes precedence over ' + 'the theme from DefaultSvgTheme', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + currentColor: Color(0xFF733821), + ); + + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + currentColor: Color(0xFF05290E), + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + svgPicture.pictureProvider.currentColor, + equals(Color(0xFF05290E)), + ); + }); + }); +} diff --git a/third_party/test/picture_cache_test.dart b/third_party/test/picture_cache_test.dart index 2876fb38fcf9..89542ced31bc 100644 --- a/third_party/test/picture_cache_test.dart +++ b/third_party/test/picture_cache_test.dart @@ -75,7 +75,7 @@ void main() { expect(PictureProvider.cache.count, 0); await precachePicture( StringPicture( - SvgPicture.svgStringDecoder, + SvgPicture.svgStringDecoderBuilder, svgString, ), tester.element(find.text('test_text')), @@ -110,7 +110,7 @@ void main() { expect(PictureProvider.cache.count, 0); await precachePicture( StringPicture( - SvgPicture.svgStringDecoder, + SvgPicture.svgStringDecoderBuilder, svgString, ), null, @@ -135,7 +135,7 @@ void main() { await precachePicture( StringPicture( - SvgPicture.svgStringDecoder, + SvgPicture.svgStringDecoderBuilder, svgString, ), tester.element(find.text('test_text')), diff --git a/third_party/test/picture_provider_test.dart b/third_party/test/picture_provider_test.dart new file mode 100644 index 000000000000..01e4a5c8ce8a --- /dev/null +++ b/third_party/test/picture_provider_test.dart @@ -0,0 +1,146 @@ +import 'dart:io'; +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:test/test.dart'; + +class MockPictureInfo extends Mock implements PictureInfo {} + +class MockFile extends Mock implements File {} + +void main() { + group('PictureProvider', () { + Color? currentColor; + + PictureInfoDecoder decoderBuilder(Color? color) { + currentColor = color; + return (T bytes, ColorFilter? colorFilter, String key) async => + MockPictureInfo(); + } + + test( + 'NetworkPicture rebuilds the decoder using decoderBuilder ' + 'when currentColor changes', () async { + const Color color = Color(0xFFB0E3BE); + final NetworkPicture networkPicture = + NetworkPicture(decoderBuilder, 'url'); + + final PictureInfoDecoder decoder = networkPicture.decoder; + + expect(decoder, isNotNull); + + // Update the currentColor of PictureProvider. + networkPicture.currentColor = color; + + expect( + decoder, + isNot(equals(networkPicture.decoder)), + ); + + expect( + currentColor, + equals(color), + ); + }); + + test( + 'FilePicture rebuilds the decoder using decoderBuilder ' + 'when currentColor changes', () async { + const Color color = Color(0xFFB0E3BE); + final FilePicture filePicture = FilePicture(decoderBuilder, MockFile()); + + final PictureInfoDecoder decoder = filePicture.decoder; + + expect(decoder, isNotNull); + + // Update the currentColor of PictureProvider. + filePicture.currentColor = color; + + expect( + decoder, + isNot(equals(filePicture.decoder)), + ); + + expect( + currentColor, + equals(color), + ); + }); + + test( + 'MemoryPicture rebuilds the decoder using decoderBuilder ' + 'when currentColor changes', () async { + const Color color = Color(0xFFB0E3BE); + final MemoryPicture memoryPicture = + MemoryPicture(decoderBuilder, Uint8List(0)); + + final PictureInfoDecoder decoder = memoryPicture.decoder; + + expect(decoder, isNotNull); + + // Update the currentColor of PictureProvider. + memoryPicture.currentColor = color; + + expect( + decoder, + isNot(equals(memoryPicture.decoder)), + ); + + expect( + currentColor, + equals(color), + ); + }); + + test( + 'StringPicture rebuilds the decoder using decoderBuilder ' + 'when currentColor changes', () async { + const Color color = Color(0xFFB0E3BE); + final StringPicture stringPicture = StringPicture(decoderBuilder, ''); + + final PictureInfoDecoder decoder = stringPicture.decoder; + + expect(decoder, isNotNull); + + // Update the currentColor of PictureProvider. + stringPicture.currentColor = color; + + expect( + decoder, + isNot(equals(stringPicture.decoder)), + ); + + expect( + currentColor, + equals(color), + ); + }); + + test( + 'ExactAssetPicture rebuilds the decoder using decoderBuilder ' + 'when currentColor changes', () async { + const Color color = Color(0xFFB0E3BE); + final ExactAssetPicture exactAssetPicture = + ExactAssetPicture(decoderBuilder, ''); + + final PictureInfoDecoder decoder = exactAssetPicture.decoder; + + expect(decoder, isNotNull); + + // Update the currentColor of PictureProvider. + exactAssetPicture.currentColor = color; + + expect( + decoder, + isNot(equals(exactAssetPicture.decoder)), + ); + + expect( + currentColor, + equals(color), + ); + }); + }); +} diff --git a/third_party/test/svg_parsers_test.dart b/third_party/test/svg_parsers_test.dart index a6f1e5ba9af6..60614f43ae9c 100644 --- a/third_party/test/svg_parsers_test.dart +++ b/third_party/test/svg_parsers_test.dart @@ -1,7 +1,8 @@ -import 'dart:ui' show PathFillType; +import 'dart:ui' show Color, PathFillType; import 'package:flutter_svg/parser.dart'; import 'package:flutter_svg/src/svg/parsers.dart'; +import 'package:flutter_svg/src/svg/theme.dart'; import 'package:flutter_svg/src/vector_drawable.dart'; import 'package:test/test.dart'; import 'package:vector_math/vector_math_64.dart'; @@ -273,4 +274,286 @@ void main() { // Empty text elements get removed expect(find(root, 'remove-space') != null, false); }); + + group('currentColor', () { + group('stroke', () { + test( + 'respects currentColor from SvgTheme ' + 'when no color attribute exists on the parent', () async { + const String svgStr = ''' + + +'''; + + const Color currentColor = Color(0xFFB0E3BE); + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme(currentColor: currentColor), + ); + + final DrawableShape? circle = find(root, 'circle'); + + expect(circle, isNotNull); + + expect( + circle!.style.stroke?.color, + equals(currentColor), + ); + }); + + test( + 'respects currentColor from SvgTheme ' + 'when the parent uses currentColor', () async { + const String svgStr = ''' + + + + +'''; + + const Color currentColor = Color(0xFFB0E3BE); + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme(currentColor: currentColor), + ); + + final DrawableShape? circle = find(root, 'circle'); + + expect(circle, isNotNull); + + expect( + circle!.style.stroke?.color, + equals(currentColor), + ); + }); + + test( + 'respects currentColor from the parent ' + 'when the parent overrides currentColor', () async { + const String svgStr = ''' + + + + +'''; + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme(currentColor: Color(0xFFB0E3BE)), + ); + + final DrawableShape? circle = find(root, 'circle'); + + expect(circle, isNotNull); + + expect( + circle!.style.stroke?.color, + equals(const Color(0xffC460B7)), + ); + }); + }); + + group('fill', () { + test( + 'respects currentColor from SvgTheme ' + 'when no color attribute exists on the parent', () async { + const String svgStr = ''' + + +'''; + + const Color currentColor = Color(0xFFB0E3BE); + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme(currentColor: currentColor), + ); + + final DrawableShape? circle = find(root, 'circle'); + + expect(circle, isNotNull); + + expect( + circle!.style.fill?.color, + equals(currentColor), + ); + }); + + test( + 'respects currentColor from SvgTheme ' + 'when the parent uses currentColor', () async { + const String svgStr = ''' + + + + +'''; + + const Color currentColor = Color(0xFFB0E3BE); + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme(currentColor: currentColor), + ); + + final DrawableShape? circle = find(root, 'circle'); + + expect(circle, isNotNull); + + expect( + circle!.style.fill?.color, + equals(currentColor), + ); + }); + + test( + 'respects currentColor from the parent ' + 'when the parent overrides currentColor', () async { + const String svgStr = ''' + + + + +'''; + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme(currentColor: Color(0xFFB0E3BE)), + ); + + final DrawableShape? circle = find(root, 'circle'); + + expect(circle, isNotNull); + + expect( + circle!.style.fill?.color, + equals(const Color(0xFFC460B7)), + ); + }); + }); + + group('stop-color', () { + test( + 'respects currentColor from SvgTheme ' + 'when no color attribute exists on the parent', () async { + const String svgStr = ''' + + + + + + + + +'''; + + const Color currentColor = Color(0xFFB0E3BE); + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme(currentColor: currentColor), + ); + + final DrawableLinearGradient? gradient = + root.definitions.getGradient('url(#gradient-1)'); + + expect(gradient, isNotNull); + + expect( + gradient!.colors?[0], + equals(currentColor.withOpacity(0.5)), + ); + + expect( + gradient.colors?[1], + equals(currentColor.withOpacity(0.8)), + ); + }); + + test( + 'respects currentColor from SvgTheme ' + 'when the parent uses currentColor', () async { + const String svgStr = ''' + + + + + + + + +'''; + + const Color currentColor = Color(0xFFB0E3BE); + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme(currentColor: currentColor), + ); + + final DrawableLinearGradient? gradient = + root.definitions.getGradient('url(#gradient-1)'); + + expect(gradient, isNotNull); + + expect( + gradient!.colors?[0], + equals(currentColor.withOpacity(0.5)), + ); + + expect( + gradient.colors?[1], + equals(currentColor.withOpacity(0.8)), + ); + }); + + test( + 'respects currentColor from the parent ' + 'when the parent overrides currentColor', () async { + const String svgStr = ''' + + + + + + + + + + +'''; + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme(currentColor: Color(0xFFB0E3BE)), + ); + + final DrawableLinearGradient? gradient = + root.definitions.getGradient('url(#gradient-1)'); + + expect(gradient, isNotNull); + + expect( + gradient!.colors?[0], + equals(const Color(0xFFC460B7).withOpacity(0.5)), + ); + + expect( + gradient.colors?[1], + equals(const Color(0xFFC460B7).withOpacity(0.8)), + ); + }); + }); + }); } diff --git a/third_party/test/theme_test.dart b/third_party/test/theme_test.dart new file mode 100644 index 000000000000..af2d270f9bcd --- /dev/null +++ b/third_party/test/theme_test.dart @@ -0,0 +1,33 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/src/svg/theme.dart'; +import 'package:test/test.dart'; + +void main() { + group('SvgTheme', () { + group('constructor', () { + test('sets currentColor', () { + const Color currentColor = Color(0xFFB0E3BE); + + expect( + SvgTheme(currentColor: currentColor).currentColor, + equals(currentColor), + ); + }); + }); + + test('supports value equality', () { + expect( + SvgTheme( + currentColor: Color(0xFF6F2173), + ), + equals( + SvgTheme( + currentColor: Color(0xFF6F2173), + ), + ), + ); + }); + }); +} diff --git a/third_party/test/vector_drawable_test.dart b/third_party/test/vector_drawable_test.dart index b2c2dcfdf413..8aa45d5d77ab 100644 --- a/third_party/test/vector_drawable_test.dart +++ b/third_party/test/vector_drawable_test.dart @@ -2,6 +2,7 @@ import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_svg/src/svg/theme.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { @@ -34,6 +35,7 @@ void main() { ''', false, const ColorFilter.mode(Color(0xFF00FF00), BlendMode.color), + const SvgTheme(), 'test', ); final Image image = await info.picture.toImage(2, 2); diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index ed89f9fe9520..0fbc5f7c3762 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -8,6 +8,7 @@ import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_svg/src/svg/theme.dart'; import 'package:flutter_svg/src/unbounded_color_filtered.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -566,6 +567,7 @@ void main() { (WidgetTester tester) async { await svg.fromSvgString( '', + const SvgTheme(), 'test'); final UnsupportedError error = tester.takeException() as UnsupportedError; expect(error.message, 'Unsupported nested element.'); diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index 0243aaab624d..46001688cdf5 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/src/svg/xml_parsers.dart'; import 'package:flutter_svg/src/utilities/xml.dart'; import 'package:test/test.dart'; @@ -197,4 +198,42 @@ void main() { expect(parseTextDecorationStyle(null), isNull); expect(() => parseTextDecorationStyle('invalid'), throwsUnsupportedError); }); + + group('parseStyle', () { + test('uses currentColor for stroke color', () { + const Color currentColor = Color(0xFFB0E3BE); + final XmlStartElementEvent svg = + parseEvents('').first + as XmlStartElementEvent; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + currentColor: currentColor, + ); + + expect(svgStyle.stroke?.color, equals(currentColor)); + }); + + test('uses currentColor for fill color', () { + const Color currentColor = Color(0xFFB0E3BE); + final XmlStartElementEvent svg = + parseEvents('').first + as XmlStartElementEvent; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + currentColor: currentColor, + ); + + expect(svgStyle.fill?.color, equals(currentColor)); + }); + }); } diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index afb04a1d99f9..c9fd1d9b19db 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -9,6 +9,7 @@ import 'dart:io'; import 'dart:typed_data'; import 'dart:ui'; +import 'package:flutter_svg/src/svg/theme.dart'; import 'package:flutter_svg/src/vector_drawable.dart'; import 'package:flutter_svg/svg.dart'; import 'package:path/path.dart' as path; @@ -20,7 +21,7 @@ Future getSvgImage(String svgData) async { const Size size = Size(200.0, 200.0); final DrawableRoot svgRoot = - await svg.fromSvgString(svgData, 'GenGoldenTest'); + await svg.fromSvgString(svgData, const SvgTheme(), 'GenGoldenTest'); svgRoot.scaleCanvasToViewBox(canvas, size); svgRoot.clipCanvasToViewBox(canvas); From c444f12b65f2649de1e76a227bbabcebc55f28a4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 8 Oct 2021 16:15:54 -0700 Subject: [PATCH 403/512] Update flutter_svg.dart --- third_party/lib/flutter_svg.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/third_party/lib/flutter_svg.dart b/third_party/lib/flutter_svg.dart index f1171ffa986e..338ad186b778 100644 --- a/third_party/lib/flutter_svg.dart +++ b/third_party/lib/flutter_svg.dart @@ -1,4 +1,6 @@ export 'src/picture_provider.dart'; export 'src/picture_stream.dart'; +export 'src/svg/default_theme.dart'; +export 'src/svg/theme.dart'; export 'src/vector_drawable.dart'; export 'svg.dart'; From ecde865370fb17057235c55377e2f6f4b5870c16 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 11 Oct 2021 11:56:39 -0700 Subject: [PATCH 404/512] Make the SvgTheme change less breaking (#606) --- .../flutter/generated_plugin_registrant.cc | 2 + .../flutter/generated_plugin_registrant.h | 2 + .../flutter/generated_plugin_registrant.cc | 2 + .../flutter/generated_plugin_registrant.h | 2 + third_party/lib/avd.dart | 1 - third_party/lib/svg.dart | 79 ++++++++++++++----- third_party/test/default_theme_test.dart | 2 - third_party/test/vector_drawable_test.dart | 3 +- third_party/test/widget_svg_test.dart | 9 +-- third_party/tool/gen_golden.dart | 3 +- 10 files changed, 73 insertions(+), 32 deletions(-) diff --git a/third_party/example/linux/flutter/generated_plugin_registrant.cc b/third_party/example/linux/flutter/generated_plugin_registrant.cc index d38195aa0412..e71a16d23d05 100644 --- a/third_party/example/linux/flutter/generated_plugin_registrant.cc +++ b/third_party/example/linux/flutter/generated_plugin_registrant.cc @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" diff --git a/third_party/example/linux/flutter/generated_plugin_registrant.h b/third_party/example/linux/flutter/generated_plugin_registrant.h index 9bf7478940c1..e0f0a47bc08f 100644 --- a/third_party/example/linux/flutter/generated_plugin_registrant.h +++ b/third_party/example/linux/flutter/generated_plugin_registrant.h @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ diff --git a/third_party/example/windows/flutter/generated_plugin_registrant.cc b/third_party/example/windows/flutter/generated_plugin_registrant.cc index 4bfa0f3a3a75..8b6d4680af38 100644 --- a/third_party/example/windows/flutter/generated_plugin_registrant.cc +++ b/third_party/example/windows/flutter/generated_plugin_registrant.cc @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" diff --git a/third_party/example/windows/flutter/generated_plugin_registrant.h b/third_party/example/windows/flutter/generated_plugin_registrant.h index 9846246b4dac..dc139d85a931 100644 --- a/third_party/example/windows/flutter/generated_plugin_registrant.h +++ b/third_party/example/windows/flutter/generated_plugin_registrant.h @@ -2,6 +2,8 @@ // Generated file. Do not edit. // +// clang-format off + #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index fff441d8d11b..d997667d6e79 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -3,7 +3,6 @@ import 'dart:typed_data'; import 'dart:ui' show Picture; import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart' show AssetBundle; import 'package:flutter/widgets.dart'; import 'package:xml/xml.dart'; diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index bbc51d9cc4a8..729deb4213b9 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -6,7 +6,6 @@ import 'dart:ui' show Picture; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; -import 'package:flutter/services.dart' show AssetBundle; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/src/svg/default_theme.dart'; @@ -50,10 +49,10 @@ class Svg { Uint8List raw, bool allowDrawingOutsideOfViewBox, ColorFilter? colorFilter, - SvgTheme theme, - String key, - ) async { - final DrawableRoot svgRoot = await fromSvgBytes(raw, theme, key); + String key, { + SvgTheme theme = const SvgTheme(), + }) async { + final DrawableRoot svgRoot = await fromSvgBytes(raw, key, theme: theme); final Picture pic = svgRoot.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter, @@ -79,10 +78,10 @@ class Svg { String raw, bool allowDrawingOutsideOfViewBox, ColorFilter? colorFilter, - SvgTheme theme, - String key, - ) async { - final DrawableRoot svg = await fromSvgString(raw, theme, key); + String key, { + SvgTheme theme = const SvgTheme(), + }) async { + final DrawableRoot svg = await fromSvgString(raw, key, theme: theme); return PictureInfo( picture: svg.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, @@ -100,15 +99,15 @@ class Svg { /// The `key` will be used for debugging purposes. Future fromSvgBytes( Uint8List raw, - SvgTheme theme, - String key, - ) async { + String key, { + SvgTheme theme = const SvgTheme(), + }) async { // TODO(dnfield): do utf decoding in another thread? // Might just have to live with potentially slow(ish) decoding, this is causing errors. // See: https://github.com/dart-lang/sdk/issues/31954 // See: https://github.com/flutter/flutter/blob/bf3bd7667f07709d0b817ebfcb6972782cfef637/packages/flutter/lib/src/services/asset_bundle.dart#L66 // if (raw.lengthInBytes < 20 * 1024) { - return fromSvgString(utf8.decode(raw), theme, key); + return fromSvgString(utf8.decode(raw), key, theme: theme); // } else { // final String str = // await compute(_utf8Decode, raw, debugLabel: 'UTF8 decode for SVG'); @@ -125,9 +124,9 @@ class Svg { /// The `key` is used for debugging purposes. Future fromSvgString( String rawSvg, - SvgTheme theme, - String key, - ) async { + String key, { + SvgTheme theme = const SvgTheme(), + }) async { final SvgParser parser = SvgParser(); return await parser.parse(rawSvg, theme: theme, key: key); } @@ -199,6 +198,46 @@ Future precachePicture( /// filtering used into the key (meaning the same SVG with two different `color` /// arguments applied would be two cache entries). class SvgPicture extends StatefulWidget { + /// Instantiates a widget that renders an SVG picture using the `pictureProvider`. + /// + /// Either the [width] and [height] arguments should be specified, or the + /// widget should be placed in a context that sets tight layout constraints. + /// Otherwise, the image dimensions will change as the image is loaded, which + /// will result in ugly layout changes. + /// + /// If `matchTextDirection` is set to true, the picture will be flipped + /// horizontally in [TextDirection.rtl] contexts. + /// + /// The `allowDrawingOutsideOfViewBox` parameter should be used with caution - + /// if set to true, it will not clip the canvas used internally to the view box, + /// meaning the picture may draw beyond the intended area and lead to undefined + /// behavior or additional memory overhead. + /// + /// A custom `placeholderBuilder` can be specified for cases where decoding or + /// acquiring data may take a noticeably long time, e.g. for a network picture. + /// + /// The `semanticsLabel` can be used to identify the purpose of this picture for + /// screen reading software. + /// + /// If [excludeFromSemantics] is true, then [semanticLabel] will be ignored. + const SvgPicture( + this.pictureProvider, { + Key? key, + this.width, + this.height, + this.fit = BoxFit.contain, + this.alignment = Alignment.center, + this.matchTextDirection = false, + this.allowDrawingOutsideViewBox = false, + this.placeholderBuilder, + this.colorFilter, + this.semanticsLabel, + this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, + this.cacheColorFilter = false, + this.currentColor, + }) : super(key: key); + /// Instantiates a widget that renders an SVG picture from an [AssetBundle]. /// /// The key will be derived from the `assetName`, `package`, and `bundle` @@ -562,8 +601,8 @@ class SvgPicture extends StatefulWidget { bytes, false, colorFilter, - SvgTheme(currentColor: currentColor), key, + theme: SvgTheme(currentColor: currentColor), ); /// A [PictureInfoDecoderBuilder] for strings that will clip to the viewBox. @@ -574,8 +613,8 @@ class SvgPicture extends StatefulWidget { data, false, colorFilter, - SvgTheme(currentColor: currentColor), key, + theme: SvgTheme(currentColor: currentColor), ); /// A [PictureInfoDecoderBuilder] for [Uint8List]s that will not clip to the viewBox. @@ -586,8 +625,8 @@ class SvgPicture extends StatefulWidget { bytes, true, colorFilter, - SvgTheme(currentColor: currentColor), key, + theme: SvgTheme(currentColor: currentColor), ); /// A [PictureInfoDecoderBuilder] for [String]s that will not clip to the viewBox. @@ -598,8 +637,8 @@ class SvgPicture extends StatefulWidget { data, true, colorFilter, - SvgTheme(currentColor: currentColor), key, + theme: SvgTheme(currentColor: currentColor), ); /// If specified, the width to use for the SVG. If unspecified, the SVG diff --git a/third_party/test/default_theme_test.dart b/third_party/test/default_theme_test.dart index b5cd4fc67ff8..5680a75762c9 100644 --- a/third_party/test/default_theme_test.dart +++ b/third_party/test/default_theme_test.dart @@ -3,8 +3,6 @@ import 'dart:ui'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_svg/src/svg/default_theme.dart'; -import 'package:flutter_svg/src/svg/theme.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { diff --git a/third_party/test/vector_drawable_test.dart b/third_party/test/vector_drawable_test.dart index 8aa45d5d77ab..32f62b916966 100644 --- a/third_party/test/vector_drawable_test.dart +++ b/third_party/test/vector_drawable_test.dart @@ -2,7 +2,6 @@ import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_svg/src/svg/theme.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { @@ -35,8 +34,8 @@ void main() { ''', false, const ColorFilter.mode(Color(0xFF00FF00), BlendMode.color), - const SvgTheme(), 'test', + theme: const SvgTheme(), ); final Image image = await info.picture.toImage(2, 2); final ByteData data = (await image.toByteData())!; diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 0fbc5f7c3762..df94eb65f930 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -5,10 +5,8 @@ import 'dart:typed_data'; import 'dart:ui' show window; import 'package:flutter/rendering.dart'; -import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_svg/src/svg/theme.dart'; import 'package:flutter_svg/src/unbounded_color_filtered.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -566,9 +564,10 @@ void main() { testWidgets('Nested SVG elements report a FlutterError', (WidgetTester tester) async { await svg.fromSvgString( - '', - const SvgTheme(), - 'test'); + '', + 'test', + theme: const SvgTheme(), + ); final UnsupportedError error = tester.takeException() as UnsupportedError; expect(error.message, 'Unsupported nested element.'); }); diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index c9fd1d9b19db..afb04a1d99f9 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -9,7 +9,6 @@ import 'dart:io'; import 'dart:typed_data'; import 'dart:ui'; -import 'package:flutter_svg/src/svg/theme.dart'; import 'package:flutter_svg/src/vector_drawable.dart'; import 'package:flutter_svg/svg.dart'; import 'package:path/path.dart' as path; @@ -21,7 +20,7 @@ Future getSvgImage(String svgData) async { const Size size = Size(200.0, 200.0); final DrawableRoot svgRoot = - await svg.fromSvgString(svgData, const SvgTheme(), 'GenGoldenTest'); + await svg.fromSvgString(svgData, 'GenGoldenTest'); svgRoot.scaleCanvasToViewBox(canvas, size); svgRoot.clipCanvasToViewBox(canvas); From 10564fc55127e7e3a1d73b46589bdc53c95da32f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 12 Oct 2021 22:12:47 -0700 Subject: [PATCH 405/512] bumps --- third_party/CHANGELOG.md | 8 ++++++++ third_party/pubspec.yaml | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index f464bfcc65bc..0f592133a1f3 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,13 @@ # CHANGES +## 0.23.0 + +- Support for currentColor +- Some API breaks around PictureProvider to support currentColor +- Support for `xml:space` +- Support for `text-decoration` +- Support for `font-style` + ## 0.22.1 - Pick up performance improvements in path_parsing 0.2.1 diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 87ac0858a344..b2212def6088 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 0.22.1 +version: 0.23.0 dependencies: flutter: From 5c3992eacd2da543bc39a95fb233d78ca8884338 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 12 Oct 2021 22:16:25 -0700 Subject: [PATCH 406/512] Bump again --- third_party/CHANGELOG.md | 4 ++++ third_party/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 0f592133a1f3..0137c0ab2c73 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 0.23.0+1 + +- Missing commit that reduced breakages introduced in 0.23.0 + ## 0.23.0 - Support for currentColor diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index b2212def6088..fdb963fa78e5 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 0.23.0 +version: 0.23.0+1 dependencies: flutter: From 0442e13ac30dab90c2f842c1dcf06358012cd932 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 12 Oct 2021 22:39:03 -0700 Subject: [PATCH 407/512] Improve performance when an animation is present over the SVG (#592) - Use repaint boundaries and layers to make sure that SVGs are more raster cache friendly with current limitations in Flutter - Avoid repatining SVG every time an overlapping animation moves - Release picture memory eagerly --- .../macos/Runner.xcodeproj/project.pbxproj | 14 +- third_party/example/test_driver/repaint.dart | 19 +++ .../example/test_driver/repaint_test.dart | 21 +++ third_party/lib/avd.dart | 33 +++-- third_party/lib/src/picture_cache.dart | 20 ++- third_party/lib/src/picture_stream.dart | 49 +++++-- third_party/lib/src/render_picture.dart | 133 +++++++++++++----- .../lib/src/unbounded_color_filtered.dart | 54 ------- third_party/lib/src/vector_drawable.dart | 9 +- third_party/lib/svg.dart | 39 ++--- .../test/golden_widget/columns_and_rows.png | Bin 25781 -> 6193 bytes .../test/golden_widget/flutter_logo.asset.png | Bin 10330 -> 10130 bytes .../golden_widget/flutter_logo.memory.png | Bin 10330 -> 10130 bytes .../golden_widget/flutter_logo.network.png | Bin 10330 -> 10130 bytes ...go.string.color_filter.blendmode_color.png | Bin 9223 -> 9032 bytes .../flutter_logo.string.color_filter.png | Bin 7618 -> 7518 bytes .../golden_widget/flutter_logo.string.ltr.png | Bin 3404 -> 3411 bytes .../golden_widget/flutter_logo.string.png | Bin 10330 -> 10130 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 3490 -> 3496 bytes third_party/test/picture_cache_test.dart | 46 +++++- third_party/test/picture_stream_test.dart | 89 +++++++++++- third_party/test/vector_drawable_test.dart | 16 +++ third_party/test/widget_svg_test.dart | 3 +- 23 files changed, 385 insertions(+), 160 deletions(-) create mode 100644 third_party/example/test_driver/repaint.dart create mode 100644 third_party/example/test_driver/repaint_test.dart delete mode 100644 third_party/lib/src/unbounded_color_filtered.dart diff --git a/third_party/example/macos/Runner.xcodeproj/project.pbxproj b/third_party/example/macos/Runner.xcodeproj/project.pbxproj index 331479d3989a..ef1b05f476cf 100644 --- a/third_party/example/macos/Runner.xcodeproj/project.pbxproj +++ b/third_party/example/macos/Runner.xcodeproj/project.pbxproj @@ -26,10 +26,6 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; }; - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; }; - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */ = {isa = PBXBuildFile; fileRef = D73912EF22F37F9E000D13A0 /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -49,8 +45,6 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( - D73912F222F3801D000D13A0 /* App.framework in Bundle Framework */, - 33D1A10522148B93006C7A3E /* FlutterMacOS.framework in Bundle Framework */, ); name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; @@ -69,13 +63,11 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Debug.xcconfig"; sourceTree = ""; }; 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Flutter-Release.xcconfig"; sourceTree = ""; }; 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = "Flutter-Generated.xcconfig"; path = "ephemeral/Flutter-Generated.xcconfig"; sourceTree = ""; }; - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FlutterMacOS.framework; path = Flutter/ephemeral/FlutterMacOS.framework; sourceTree = SOURCE_ROOT; }; 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; - D73912EF22F37F9E000D13A0 /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/ephemeral/App.framework; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -83,8 +75,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - D73912F022F37F9E000D13A0 /* App.framework in Frameworks */, - 33D1A10422148B71006C7A3E /* FlutterMacOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -138,8 +128,6 @@ 33CEB47222A05771004F2AC0 /* Flutter-Debug.xcconfig */, 33CEB47422A05771004F2AC0 /* Flutter-Release.xcconfig */, 33CEB47722A0578A004F2AC0 /* Flutter-Generated.xcconfig */, - D73912EF22F37F9E000D13A0 /* App.framework */, - 33D1A10322148B71006C7A3E /* FlutterMacOS.framework */, ); path = Flutter; sourceTree = ""; @@ -260,7 +248,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename\n"; + shellScript = "echo \"$PRODUCT_NAME.app\" > \"$PROJECT_DIR\"/Flutter/ephemeral/.app_filename && \"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh embed\n"; }; 33CC111E2044C6BF0003C045 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; diff --git a/third_party/example/test_driver/repaint.dart b/third_party/example/test_driver/repaint.dart new file mode 100644 index 000000000000..45891f37b476 --- /dev/null +++ b/third_party/example/test_driver/repaint.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_driver/driver_extension.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +void main() { + enableFlutterDriverExtension(); + runApp( + Directionality( + textDirection: TextDirection.ltr, + child: Stack( + alignment: Alignment.center, + children: [ + SvgPicture.asset('assets/wikimedia/Ghostscript_Tiger.svg'), + const CircularProgressIndicator(), + ], + ), + ), + ); +} diff --git a/third_party/example/test_driver/repaint_test.dart b/third_party/example/test_driver/repaint_test.dart new file mode 100644 index 000000000000..99bc518ef313 --- /dev/null +++ b/third_party/example/test_driver/repaint_test.dart @@ -0,0 +1,21 @@ +import 'package:flutter_driver/flutter_driver.dart'; + +Future main() async { + final FlutterDriver driver = await FlutterDriver.connect(); + try { + await driver.waitUntilFirstFrameRasterized(); + await Future.delayed(const Duration(milliseconds: 1000)); + await driver.forceGC(); + await driver.clearTimeline(); + await Future.delayed(const Duration(milliseconds: 1000)); + + final Timeline timeline = await driver.traceAction(() async { + // animate + await Future.delayed(const Duration(seconds: 10)); + }); + final TimelineSummary summary = TimelineSummary.summarize(timeline); + await summary.writeTimelineToFile('repaint', pretty: true); + } finally { + await driver.close(); + } +} diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index d997667d6e79..a38a0f277ae6 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -3,6 +3,7 @@ import 'dart:typed_data'; import 'dart:ui' show Picture; import 'package:flutter/foundation.dart'; +import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:xml/xml.dart'; @@ -11,7 +12,6 @@ import 'src/avd_parser.dart'; import 'src/picture_provider.dart'; import 'src/picture_stream.dart'; import 'src/render_picture.dart'; -import 'src/unbounded_color_filtered.dart'; import 'src/vector_drawable.dart'; /// Instance for [Avd]'s utility methods, which can produce [DrawableRoot] or @@ -35,7 +35,14 @@ class Avd { final Picture pic = avdRoot.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter); - return PictureInfo(picture: pic, viewport: avdRoot.viewport.viewBoxRect); + final LayerHandle handle = LayerHandle(); + handle.layer = PictureLayer(avdRoot.viewport.viewBoxRect) + ..picture = pic + ..isComplexHint = true; + return PictureInfo( + layerHandle: handle, + viewport: avdRoot.viewport.viewBoxRect, + ); } /// Decodes an Android Vector Drawable from a [String] to a [PictureInfo] @@ -46,13 +53,19 @@ class Avd { ColorFilter? colorFilter, String key, ) async { - final DrawableRoot avd = fromAvdString(raw, key); + final DrawableRoot avdRoot = fromAvdString(raw, key); + final Picture pic = avdRoot.toPicture( + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, + colorFilter: colorFilter, + ); + final LayerHandle handle = LayerHandle(); + handle.layer = PictureLayer(avdRoot.viewport.viewBoxRect) + ..picture = pic + ..isComplexHint = true; return PictureInfo( - picture: avd.toPicture( - clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, - colorFilter: colorFilter), - viewport: avd.viewport.viewBoxRect, - size: avd.viewport.size, + layerHandle: handle, + viewport: avdRoot.viewport.viewBoxRect, + size: avdRoot.viewport.size, ); } @@ -320,8 +333,8 @@ class _AvdPictureState extends State { if (widget.pictureProvider.colorFilter == null && widget.colorFilter != null) { - child = UnboundedColorFiltered( - colorFilter: widget.colorFilter, + child = ColorFiltered( + colorFilter: widget.colorFilter!, child: child, ); } diff --git a/third_party/lib/src/picture_cache.dart b/third_party/lib/src/picture_cache.dart index a06d7a2c0d6e..239cf9a49445 100644 --- a/third_party/lib/src/picture_cache.dart +++ b/third_party/lib/src/picture_cache.dart @@ -2,7 +2,7 @@ import 'picture_stream.dart'; const int _kDefaultSize = 1000; -/// A cache for [Picture] objects. +/// A cache for [PictureLayer] objects. /// /// By default, this caches up to 1000 objects. class PictureCache { @@ -30,10 +30,10 @@ class PictureCache { } _maximumSize = value; if (maximumSize == 0) { - _cache.clear(); + clear(); } else { while (_cache.length > maximumSize) { - _cache.remove(_cache.keys.first); + _cache.remove(_cache.keys.first)!.cached = false; } } } @@ -43,6 +43,10 @@ class PictureCache { /// This is useful if, for instance, the root asset bundle has been updated /// and therefore new images must be obtained. void clear() { + for (final PictureStreamCompleter completer in _cache.values) { + assert(completer.cached); + completer.cached = false; + } _cache.clear(); } @@ -52,7 +56,9 @@ class PictureCache { /// /// The arguments must not be null. The `loader` cannot return null. PictureStreamCompleter putIfAbsent( - Object key, PictureStreamCompleter loader()) { + Object key, + PictureStreamCompleter loader(), + ) { assert(key != null); // ignore: unnecessary_null_comparison assert(loader != null); // ignore: unnecessary_null_comparison PictureStreamCompleter? result = _cache[key]; @@ -61,13 +67,15 @@ class PictureCache { // and thus move it to the end of the list. _cache.remove(key); } else { - if (_cache.length == maximumSize && maximumSize > 0) - _cache.remove(_cache.keys.first); + if (_cache.length == maximumSize && maximumSize > 0) { + _cache.remove(_cache.keys.first)!.cached = false; + } result = loader(); } if (maximumSize > 0) { assert(_cache.length < maximumSize); _cache[key] = result; + result.cached = true; } assert(_cache.length <= maximumSize); return result; diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart index 1219b5623ba7..09769adc1c94 100644 --- a/third_party/lib/src/picture_stream.dart +++ b/third_party/lib/src/picture_stream.dart @@ -6,6 +6,7 @@ import 'dart:async'; import 'dart:ui' show Picture, Rect, hashValues, Size; import 'package:flutter/foundation.dart'; +import 'package:flutter/rendering.dart'; /// The signature of a method that listens for errors on picture stream resolution. typedef PictureErrorListener = void Function( @@ -25,17 +26,22 @@ class _PictureListenerPair { class PictureInfo { /// Creates a new PictureInfo object. const PictureInfo({ - required this.picture, + required this.layerHandle, required this.viewport, this.size = Size.infinite, - }) : assert(picture != null), // ignore: unnecessary_null_comparison + }) : assert(layerHandle != null), // ignore: unnecessary_null_comparison assert(viewport != null), // ignore: unnecessary_null_comparison assert(size != null); // ignore: unnecessary_null_comparison + /// The [PictureLayer] that holds the [picture]. + final LayerHandle layerHandle; + /// The raw picture. /// - /// This is the object to pass to the [Canvas.drawPicture] when painting. - final Picture picture; + /// This picture's lifecycle will be managed by the provider. It will be + /// reused as long as the picture does not change, and disposed when the + /// provider loses all of its listeners or it is unset. + Picture get picture => layerHandle.layer!.picture!; /// The viewport enclosing the coordinates used in the picture. final Rect viewport; @@ -45,7 +51,7 @@ class PictureInfo { final Size size; @override - int get hashCode => hashValues(picture, viewport, size); + int get hashCode => hashValues(layerHandle, viewport, size); @override bool operator ==(Object other) { @@ -53,7 +59,7 @@ class PictureInfo { return false; } return other is PictureInfo && - other.picture == picture && + other.layerHandle == layerHandle && other.viewport == viewport && other.size == size; } @@ -195,6 +201,21 @@ abstract class PictureStreamCompleter with Diagnosticable { final List<_PictureListenerPair> _listeners = <_PictureListenerPair>[]; PictureInfo? _current; + bool _cached = false; + + /// Whether or not this completer is in the [PictureCache]. + bool get cached => _cached; + set cached(bool value) { + if (value == _cached) { + return; + } + if (!value && _listeners.isEmpty) { + _current?.layerHandle.layer = null; + _current = null; + } + _cached = value; + } + /// Adds a listener callback that is called whenever a new concrete [PictureInfo] /// object is available. If a concrete image is already available, this object /// will call the listener synchronously. @@ -226,11 +247,16 @@ abstract class PictureStreamCompleter with Diagnosticable { _listeners.removeWhere( (_PictureListenerPair pair) => pair.listener == listener, ); + if (_listeners.isEmpty && !cached) { + _current?.layerHandle.layer = null; + _current = null; + } } /// Calls all the registered listeners to notify them of a new picture. @protected void setPicture(PictureInfo? picture) { + _current?.layerHandle.layer = null; _current = picture; if (_listeners.isEmpty) { return; @@ -264,19 +290,18 @@ abstract class PictureStreamCompleter with Diagnosticable { )); } - /// Accumulates a list of strings describing the object's state. Subclasses - /// should override this to have their information included in [toString]. @override - void debugFillProperties(DiagnosticPropertiesBuilder description) { - super.debugFillProperties(description); - description.add(DiagnosticsProperty('current', _current, + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(DiagnosticsProperty('current', _current, ifNull: 'unresolved', showName: false)); - description.add(ObjectFlagProperty>( + properties.add(ObjectFlagProperty>( 'listeners', _listeners, ifPresent: '${_listeners.length} listener${_listeners.length == 1 ? "" : "s"}', )); + properties.add(FlagProperty('cached', value: cached, ifTrue: 'cached')); } } diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index a1cfc2ad6cd2..4ce5cf083355 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -1,5 +1,6 @@ import 'dart:math' as math; +import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'picture_stream.dart'; @@ -63,10 +64,11 @@ class RenderPicture extends RenderBox { bool matchTextDirection = false, TextDirection? textDirection, bool? allowDrawingOutsideViewBox, - }) : _picture = picture, - _matchTextDirection = matchTextDirection, + }) : _matchTextDirection = matchTextDirection, _textDirection = textDirection, - _allowDrawingOutsideViewBox = allowDrawingOutsideViewBox; + _allowDrawingOutsideViewBox = allowDrawingOutsideViewBox { + this.picture = picture; + } /// Optional color to use to draw a thin rectangle around the canvas. /// @@ -124,6 +126,13 @@ class RenderPicture extends RenderBox { return; } _picture = val; + assert(() { + if (_picture != null && _picture!.layerHandle.layer != null) { + assert(_picture!.layerHandle.layer!.isComplexHint == true); + assert(_picture!.layerHandle.layer!.willChangeHint == false); + } + return true; + }()); markNeedsPaint(); } @@ -149,23 +158,80 @@ class RenderPicture extends RenderBox { @override bool get sizedByParent => true; - // TODO(goderbauer): Remove the ignore when https://github.com/flutter/flutter/pull/70656 has landed. @override - // ignore: override_on_non_overriding_member Size computeDryLayout(BoxConstraints constraints) { return constraints.smallest; } + @override + bool get isRepaintBoundary => true; + + final LayerHandle _transformHandle = + LayerHandle(); + + final LayerHandle _clipHandle = LayerHandle(); + + void _addPicture(PaintingContext context, Offset offset) { + assert(picture != null); + if (allowDrawingOutsideViewBox != true) { + final Rect viewportRect = Offset.zero & _picture!.viewport.size; + _clipHandle.layer = context.pushClipRect( + needsCompositing, + offset, + viewportRect, + (PaintingContext context, Offset offset) { + context.addLayer(picture!.layerHandle.layer!); + }, + oldLayer: _clipHandle.layer, + ); + } else { + _clipHandle.layer = null; + context.addLayer(picture!.layerHandle.layer!); + } + } + + @override + void dispose() { + _transformHandle.layer = null; + super.dispose(); + } + @override void paint(PaintingContext context, Offset offset) { if (picture == null || size == Size.zero) { return; } - context.canvas.save(); - context.canvas.translate(offset.dx, offset.dy); + + bool needsTransform = false; + final Matrix4 transform = Matrix4.identity(); + if (_flipHorizontally) { - context.canvas.translate(size.width, 0.0); - context.canvas.scale(-1.0, 1.0); + needsTransform = true; + transform + ..translate(size.width, 0.0) + ..scale(-1.0, 1.0); + } + + if (scaleCanvasToViewBox( + transform, + size, + _picture!.viewport, + _picture!.size, + )) { + needsTransform = true; + } + + if (needsTransform) { + _transformHandle.layer = context.pushTransform( + needsCompositing, + offset, + transform, + _addPicture, + oldLayer: _transformHandle.layer, + ); + } else { + _transformHandle.layer = null; + _addPicture(context, offset); } // this is sometimes useful for debugging, e.g. to draw @@ -181,41 +247,34 @@ class RenderPicture extends RenderBox { } return true; }()); - scaleCanvasToViewBox( - context.canvas, - size, - _picture!.viewport, - _picture!.size, - ); - final Rect viewportRect = Offset.zero & _picture!.viewport.size; - if (allowDrawingOutsideViewBox != true) { - context.canvas.clipRect(viewportRect); - } - context.canvas.drawPicture(picture!.picture); - context.canvas.restore(); } } -/// Scales a [Canvas] to a given [viewBox] based on the [desiredSize] +/// Scales a matrix to the given [viewBox] based on the [desiredSize] /// of the widget. -void scaleCanvasToViewBox( - Canvas canvas, +/// +/// Returns true if the supplied matrix was modified. +bool scaleCanvasToViewBox( + Matrix4 matrix, Size desiredSize, Rect viewBox, Size pictureSize, ) { - if (desiredSize != viewBox.size) { - final double scale = math.min( - desiredSize.width / viewBox.width, - desiredSize.height / viewBox.height, - ); - final Size scaledHalfViewBoxSize = viewBox.size * scale / 2.0; - final Size halfDesiredSize = desiredSize / 2.0; - final Offset shift = Offset( - halfDesiredSize.width - scaledHalfViewBoxSize.width, - halfDesiredSize.height - scaledHalfViewBoxSize.height, - ); - canvas.translate(shift.dx, shift.dy); - canvas.scale(scale, scale); + if (desiredSize == viewBox.size) { + return false; } + final double scale = math.min( + desiredSize.width / viewBox.width, + desiredSize.height / viewBox.height, + ); + final Size scaledHalfViewBoxSize = viewBox.size * scale / 2.0; + final Size halfDesiredSize = desiredSize / 2.0; + final Offset shift = Offset( + halfDesiredSize.width - scaledHalfViewBoxSize.width, + halfDesiredSize.height - scaledHalfViewBoxSize.height, + ); + matrix + ..translate(shift.dx, shift.dy) + ..scale(scale, scale); + return true; } diff --git a/third_party/lib/src/unbounded_color_filtered.dart b/third_party/lib/src/unbounded_color_filtered.dart deleted file mode 100644 index 1787897ff4a7..000000000000 --- a/third_party/lib/src/unbounded_color_filtered.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/rendering.dart'; -import 'package:flutter/widgets.dart'; - -/// Supports SvgPicture - not meant for public use, visible for testing. -@visibleForTesting -class UnboundedColorFiltered extends SingleChildRenderObjectWidget { - /// Supports SvgPicture - not meant for public use, visible for testing. - const UnboundedColorFiltered({ - Key? key, - required this.colorFilter, - required Widget child, - }) : super(key: key, child: child); - - /// The color filter to apply. - final ColorFilter? colorFilter; - - @override - _UnboundedColorFilteredRenderBox createRenderObject(BuildContext context) => - _UnboundedColorFilteredRenderBox(colorFilter); - - @override - void updateRenderObject( - BuildContext context, - covariant _UnboundedColorFilteredRenderBox renderObject, - ) { - renderObject.colorFilter = colorFilter; - } -} - -class _UnboundedColorFilteredRenderBox extends RenderProxyBox { - _UnboundedColorFilteredRenderBox( - this._colorFilter, - ); - - ColorFilter? _colorFilter; - ColorFilter? get colorFilter => _colorFilter; - set colorFilter(ColorFilter? value) { - if (value == _colorFilter) { - return; - } - _colorFilter = value; - markNeedsPaint(); - } - - @override - void paint(PaintingContext context, Offset offset) { - final Paint paint = Paint()..colorFilter = colorFilter; - context.canvas.saveLayer(offset & size, paint); - if (child != null) { - context.paintChild(child!, offset); - } - context.canvas.restore(); - } -} diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index bb9faf747ee4..4eabe0b20907 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -878,12 +878,15 @@ class DrawableRoot implements DrawableParent { /// the smaller dimension and translate to center the image along the larger /// dimension. void scaleCanvasToViewBox(Canvas canvas, Size desiredSize) { - render_picture.scaleCanvasToViewBox( - canvas, + final Matrix4 transform = Matrix4.identity(); + if (render_picture.scaleCanvasToViewBox( + transform, desiredSize, viewport.viewBoxRect, viewport.size, - ); + )) { + canvas.transform(transform.storage); + } } /// Clips the canvas to a rect corresponding to the `viewBox`. diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 729deb4213b9..514d63073e8f 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -14,7 +14,6 @@ import 'src/picture_provider.dart'; import 'src/picture_stream.dart'; import 'src/render_picture.dart'; import 'src/svg/theme.dart'; -import 'src/unbounded_color_filtered.dart'; import 'src/vector_drawable.dart'; /// Instance for [Svg]'s utility methods, which can produce a [DrawableRoot] @@ -57,8 +56,12 @@ class Svg { clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter, ); + final LayerHandle handle = LayerHandle(); + handle.layer = PictureLayer(svgRoot.viewport.viewBoxRect) + ..picture = pic + ..isComplexHint = true; return PictureInfo( - picture: pic, + layerHandle: handle, viewport: svgRoot.viewport.viewBoxRect, size: svgRoot.viewport.size, ); @@ -81,15 +84,20 @@ class Svg { String key, { SvgTheme theme = const SvgTheme(), }) async { - final DrawableRoot svg = await fromSvgString(raw, key, theme: theme); + final DrawableRoot svgRoot = await fromSvgString(raw, key, theme: theme); + final Picture pic = svgRoot.toPicture( + clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, + colorFilter: colorFilter, + size: svgRoot.viewport.viewBox, + ); + final LayerHandle handle = LayerHandle(); + handle.layer = PictureLayer(svgRoot.viewport.viewBoxRect) + ..picture = pic + ..isComplexHint = true; return PictureInfo( - picture: svg.toPicture( - clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, - colorFilter: colorFilter, - size: svg.viewport.viewBox, - ), - viewport: svg.viewport.viewBoxRect, - size: svg.viewport.size, + layerHandle: handle, + viewport: svgRoot.viewport.viewBoxRect, + size: svgRoot.viewport.size, ); } @@ -742,12 +750,7 @@ class _SvgPictureState extends State { void didChangeDependencies() { _updatePictureProvider(); _resolveImage(); - - if (TickerMode.of(context)) { - _listenToStream(); - } else { - _stopListeningToStream(); - } + _listenToStream(); super.didChangeDependencies(); } @@ -865,8 +868,8 @@ class _SvgPictureState extends State { if (widget.pictureProvider.colorFilter == null && widget.colorFilter != null) { - child = UnboundedColorFiltered( - colorFilter: widget.colorFilter, + child = ColorFiltered( + colorFilter: widget.colorFilter!, child: child, ); } diff --git a/third_party/test/golden_widget/columns_and_rows.png b/third_party/test/golden_widget/columns_and_rows.png index ffad57343e0b99518f7b3afee9a57b3ab78aa0ed..b97f0f8049ec67aedf1c1939d20f438687bdf1a4 100644 GIT binary patch literal 6193 zcmeHLYgkg*8s1&C$xD|h?RdemscE`ckCk_+#6XExaoiMk8c0~&_8;_gR@e!9!SmV)?em%+;-^l7(40HxD(6#TOkedwr{ zF8E2-4Z8^dM*O2L2fY#srGgVEBoD{z7v*eP_VbmaFCPIt$F{oam7UYq+4f7=UH?c- z=YB-q8++6PL1KS^a`|&gURF&O=HTb}LD$Qt+Ma~+Zn1oFf%oYh_K$*3f0mwmcXOcc zp*m;5VBeHuDnLy6^|AFo^x)`mJDMlpvdzs-CJCTivZx}g1g_M|3)T2WA82~*uIq*LimYppVu^v)G=Qf2+uaEhM6wg{x#*k zGVm7$I2&ew;Of%If)GN#tvJ@cxEfGS%)jrH=rFU^{Z~qseVchpNF=53Qo7UfaWQiK zYM44YYcZQJ*giFwFu7nG=m@4K`1ib5G0f*{5&X))Ul@RDnyHQlXK$N%+m)`-*ac!@jh= zxcVFv^%rFH=-VZ5o*`+D)e+=X7HB?WJ9~_?5HONq(rheV)rdE>3WP`W%hQ}QCgwwy zeHHqz4E%)w`?iHPV(A={G_Q1SxI4 z>SARaslR`uc#sNSMh)+z737ork@w3{?>xE&4wdaHv1)i=#(sN!oQ*J$p56&r#f*r^ z^K|?iy~^Le$9X~)7uBGMqV;46tJ9$AV4C)@ox8$(4?`B)^qSiW0;_{W3?k1b564`p z?DUFucmAk2f%0Zmi?aU7k$8t|{Pt1hp9T>bH^Ewxy2S4cN=(I!cX1_#>&;8vc?*&s zDI`;#Zq}t78o3kyUMZjMO~bL<%eILBSh@9L$Z&)eYmEf}Ox(oJ34K)JHV1`Z@EMjQ zR@Hcyyo1k*UxnlgNmwjZeAb3MjFM@n)}G#Q?2L#f_5b1w`V=aaEY3Dd@Lra(|WPu2)h zN?t!14-3HeyRh8NI!m@40Dw=<-8SSv96I#VcfPbzvQRv;KNp_ei9aP*4ZUP4<45e} zZ!$RNpheJo+SuJiM#a>QD?qeW zSR|26kbGYhB&|xXmFk0Nu|w^nOAc%4U$1OuiYrJds^P&J-e3qT#!Dra@d;9=i0ff8 zx&Z(Xeo_q#-mNDE!EG8QPjQuW)qK4$pjXi#!rxayFIZ3C;wLBH-(}n*OtY3|goHjf z+6Z&%(bT88XeX$yMER%|#KSGK31lLS^OV6gGu@ard=U;sa#4ekGxs^i>)p;#`D8AK zhC9h1>fI*1oXO1L3G1g?nh9W%1dj!r5ng1p&22>wgwkjYQWK62E64<-y2a0A+CU8k zKx^7_eUTYjGs6=0jqQtA7HOru8^u4uu(NY63vjB;svf?8X7`O?tR3n7&92D zNSr-`b2bon$10yhzK!x=sD*0fL5RlC$n%T}8|N_*ZQ^AQDQfCRKG4S1`cmKm}tsKqNF^Dz}3t+tvj9y0K4OJed;7)xwMJk zFe&c8At1&-7an6;_`#b!(&E@E*+6En%OOyPx^zy_(t&n(>9< zFfKm`_94}^g&!n?uOmknleHL2rA2du;#e{FU|&Iu=!IxM4;t{0AayJ1CZ`fykthVmHqIyrdB%1bjUu zP&7`LF~!@+u#C~}SQG+tR#cgk?YJIXsXI4B!lw$$htUWOo1rD5vA*xBjF5YmXnViT zPJr8>rROuXC|TZtlp%zsl&lW5$yy3Zh|`0>TcSoeYTycQ>M>_O&4D@j4OpvOg&&S_ z6nhq3jqM%o{szJonkW^n%K>W&`-J}NIfJn&PllZ^I(*$R2;hfYUP03!28EBd4c)Lc zX(Rzxqws^Oqib(fmileAbIFF*1FziqrlQ_e5abti`d?z46Q+BIKSG0BqGUt9-itRs zjLt?yYp3sHl2v)ZRSioeuc@rb54WMX^y(M&zc<;-gfdoprf{d0p#Yv~EW>3;tLo^L z&~$vE$Ct&M!G>y-KlGY;4GQo-2M#Sqi1`f)O}I_Eb@r873?;l&O8~_IBO^3w`(Z}5 zKutN&8HKR}=WLt#%P)V40?V1hfCn z`NFZH!Tbtg=tgLS#3ZY>0wKvBmvkg;!;&(TqU0KN%2-QhAZ=)KWlfM?h(+k5=olj- z2rKx@vH`HOk4E#0B!?eBRDIsL%Y9n9BoWKfUqNV{_Cdv9i22VKgJ|#9&vu20n8kr+ ztp{9@{KE0#B<&8J9j{lza3yrR>py|3V<&J@XcPGIWQF?eQ-mnqv$bt6{e4Qq$9G<+ zaSVjzl`H?eA6sM$j^o8g28x9aBib&LkHeKqKIgM5ubHNU>VzEs4vOh4Sjht-?EcC7 z;q^-@tN(`e+7x>{CIbRn*_ixLwRZ>Ef)Eq`ST#+qtJkLWz4jZon!IyHt4K1W3AE!d z6uHQAs5SoKnDy&ri}B2kNOx)?3mPAWwtqg&bh^ z8LEFL5*fRie{U+N&4Un)1&9&dnF6)SBD^^QJ`{<>rPQm+2aM=<<0{Upd!f}RCzTi^ z=xFlUE=Rmk2E}ugnn6fAYtJu>)M_D@-!=hC*QQ_FL74!5;F2O{pdA0S-NB@SkAGm! z)7|hbOv&Qnp_CeXE~3w~le_uXoeauCJy6~%X^LSs;UM|20_qe@P;L6WaFHuY-rcKM zkuUh7GUM+rgl%>vk?dLb?y?p!!P7v?$i%7&Ur}GVoTX+*yZfk;XyV>vJko7+;i7Cy zS~S^FCyVd{xQu}E-##EJu}Z}pRrhNp-n;f71_#EAQ_h8;Vr#F$lX%Hz1fQ0C+S?Danq7x?!rlY33 zHCLL9HWSi%vcRO01jO%qohj&;A6>cC;5%m$6u9Fr+uxp*_c~zw6*s)(yV~c&n#2M$ z)5hh34XL>KlzdwJX)WVIDQQ>p<$<4Mm(>rnoqknHSN4G7%iQh~-}+b@ArKfuHM>E= z2oS!=72{nduo!)$e$V7w1<9~;#>e#oky}Q?ZZ~5KD#2Z@sV)M|z-UhgcCPi7r3oap z|Mp{=Mo-W)!hh!l5vv>KsHA&au_0H#MTjW=vya4MFoj6;jNgu48#l*?9NC1gQ~X*B z0Jy9R37uR~CuW?0?QkJs$s27-%Ke?VbazR2hcE^H<%bS1Cl{oo9;>80UzTXRC_=s) zbFumIg-3x+yU%2<%uo6SDyOzCgf*Me##}mL9G+b{IXdwXDo>wucU13_lMQKNv0N!z zeH5}?T}7401s#?>!D~4~uC800d+&SiwfA0Yy1tKRcrS2BL zG;-gb!8~zp4+=SD`>Z!qk8(JTjXdRg@USVD`r`EpvBC+8bWieXbWfc4_x#fBav>MH zkh43FU0D~3i25Frr%r`<4W6moR^?NDs90K8WTpF&z17xP?pLn@`K92mQD<}TPW9iV zzsJ8JN5RJb-iv=@|J4KaSYFjhcl7%j?3|Sp1d>HqYRJG=eJ)v`gvipBXz&SH5sE1z zzq+OjspDN-8Q}9pC+bHBwa?Dj*1$8f?*!T1#Gj%_K6TJo^I%?4^?q^m#KU7T>Hl@g z_i@fGmUkWdpoh&TmAS!Yd9^X>#oXE5K_W2SZu#sFGcP7PYfLFg&p`ScWN0DWjvw)~ zeR}&as4rjK247cA2+J39S9_v) zzbMGscRlKSrTS~a(~u?OWD-c!fUTrpoVPdTU7}#z!K|8VOlE=MrlcjxIQfPJA;$Yq_xG6&0V)5Dc0t3VAG&lmJz{0Q@^ zt40Tv^VIjZmOXCCK{r_-k7yb6LE9gM)2Q}D3C}#&X>sOki}}TS^DV=>=0ZuT^K$08 zUGH?ehF5;Q&yGsnxvn&SFtbY&{&#W>oxWgcFs9X>zY>_($(0p$qMz+Jusu#=)km=F zyYXS>777Wx%XC6!WSr?KAbGEYuS2wGobjJlcB0xnC(OkwuH>%odUPf<*4y<5##_A@ z<5lHR5Xw=s$Yx$1p!lcBL;S84c`&_s7gj9UDo0_Lrd`>P+its43hc0{bLZ9P9)${r z$MQW-1&-MNF5>GXJPX%U{`5J9@@&O?u$E; zsg51xQLcjDoa|(axxJl=`Bg65!9N9YS&!m?$i7l(hg<1j_MUFXk+*Bgx*;lmfPO+ zKb5!&Rl`K7J60$wxdq2+@e`<{LX-Z2hByJQJTu#^A;u#Tt|Mk@E6;0R;Sd!4vx$_VfZCrnJsNn7qRYanTvtGh# zQ`#cKyNUZiyOiRDd)L+`4mmiMZN4uKjTp>~;k|EVP3~kBu`dPrdIi@w(9H8g2lVu+ z?yec%J3C?I;M8rq&sYhcpK68esalY6Vz3eHzqNaM`YGhPT}o3 zaF#lMXAp&<=` zeN$@invyV=g0Q%Qfrox*-2UpOerQ#XinkX7d*5*A$+r9LOAxjKb07W9q~UvXStpR*Jq zgCY3iIzuPFRm{n|9UVxvHs-b(^V%W?NHiC$Z#y`B+5 zNj;ndhKl_wadQv|1q{eg_G{zD_zzw?aU{~h+MSUX!gkzsUgx2qKq{eUU_2U`>L}zw< z`lp~)M|u#*BpgU3YR~RYI$nMgtT&D56!_ac@HYtLD?R7~e0ss$z$fn|?nzluKfqM;F|j4U#m`uX4$7Rf!O2Y2H=9o zq1YYN6ZIo#xrn06?S6)9K#TjvtYSTOUvjdE4&Rpnw>t|WUyP?kCrkkW^b62JeBJVA z2q3Ly*J@i4v*jm~Z6|=R7=W$tNZY%FqU>DOwhe!4IL9GhPE>U{1k#V2$=NkSjM}{1 zM&(%^MY6V4!uQV_W;7w8=SsdnLVYVHjZ-Ay4rzS1 zg2f?U$#A=;c}Su5{#t7GX&SaEMH5SUPlzv*wI3eKr7ZJj(MIj7Xw|x_?M}~>X|tlL z!6s$%=eYr4Yj)!NIb(j7TUI8v@oDxC+-TWwo&EHr^%t$DHL#~)BfiOG$9({VbgW83 zKLE|#`Vx+QN@MyojZe?uDtcERB1;E^%C>|l*t5`zC%9c68?raAnU+uZTP(Vn)cEF7 z*Tm)}ahsiZjZ1!tP9%pRo-Y?}-7ob;r@ukII&kn$HxA~nSqu&{ z^e*|Z*cyKTfkflBl!=5M57G68Pn#*OM~VAVieM5=$Y&;MJf0?JA@(F-+QMlPx<7-t zYLmA&D!VFc?mzNl+*z@!&R?%|Xz&s|3kl`M9gv?o)hSt9;|DCSbK8{Nzh}A9&%&t< zv!jd5=wJ{@G;S;^(C3V`HEYkmo zP87c+@f*uKKZ;Xed+bB2XJhBx-gi3H-)<*@q~KItXz-foPiTi+jl|q7Hj5jmuu%^&jA}vFR=7kNKlQ-B8>y2v z|6G<)1};hF$St25weZ9?xt-`?8)-9;l!a7rVst7`_2=CmEzsBZvNS7G5_w~YFps) zyB;p_RmG-Mo{flXvQJT|Rg`mR(7?yj?O%EtQ@_N9kP+OJ@XX;w22BA8|gj_%GnCcJ2iB1E0@oE4+6h_1mb~Ke7t9 zlqA#f8SJC&z`PP*?I|eoNJ}Y=4$=`f*|82d3wF?7SN-;r^kj$4CUP_7teU zA2~XRj4OrJ6g=owObzW%eF%XFg%LwSFZMLR4~F6#@CB|-aRCAafc zFVS2--Ha*3xl>yWD1&J~hqsp69{Y-NS>{1H`tlNrXDA>RQixD!vxLUAZ43-Oku9F4+jueH8;pUxU!{xw@Io(*H-6;5oE*G;d2@up8{r|s!mtViz5 zEp5Bi6ndm(FleT!XEo{uG1i_6rI~JWtGSC{Y1hi6crA?o7Zcs8_=}0)>Hj+>g5ZH3 zi1z%JOu%F(&m4oo&#vU+jw90(7W0RyYa+ubZB8kz9VsNdGDmvA29RsE<_|wP5&K^; zC6R>=1t;2$lE5r`c-(8(w~|C_Cxp(0J7%vfdS~Gj3TJjtvUuFRW9hO6VkLX?z;dY& z$X0TVRF$R=0Ts3hW^7nJVQc>fANB3!{0kr9onql>M%n`zKZ_*J54BFWotw(3Bf^0;OHPpPI~z-;k;9E?NTB5nbK!%e6c8Gz5a%qH#Zc zzg|qPn`-&I`C4JVTxE^T<=UwEu!s1r_?^>`x-jT85e_*i(NQx4P+EiaJBXIL@=*cp#Y1lbU$TGZ;{iE*C~?eGQ)$f*uaK7R$oZy z!|A5=P^dlNBF-CCQ0C}GyslQ6t`?uK?;yq;frYeoR4^Z4*@ms9(KmS71M4kIQD>{xXE!;YtQ@e zL%P{JwRuRvYi!K9Jv`uyeEkGa;i>c=uK&hZU3~y!#X*_{&?Zl(iSz*SumXfeHf)*b z%a02RA?a%T$N|8U2*%Z}6ZjUf!jhyAU#SIH@@7$EG0@mD=WBj1_Qu%KYGwO{h3Y~EWkcSzpi8CFwzeR^dPkH^y9jQj;e57g`D8%)~nZgJ^R zipJ^2U)IBuwIBu0v4PBcekq;4EH1z~SkL(0_cGmK+--%Ipr)jAY2zs;BvumfEdVPS z{zQ_Zvf~``{`9Yh0$_h=VPYE@Azd%Af#iFBY`FG|%Ki*DQDL<4Z!Ea)n~*^)?jpXu z#!9M!hFLf?<~XE_Vyq7O2aRc;#i_k-$lv$yCORzVke;~6DFk~);P|us^kva-rGIH& z%8*#)*AmnC7WE6#^#+>FN~yF_+;NX}(gIM^8M^b}h4Bq=yp)O@+bX5HkC5qLVzG6GWw`nx$?j_6}P zL1TI{2(|#MFOL9A;EN;nJEy*ZzrVBnbsC}>25q?ndxUc$|EmrCmZT$r9lM!e8pVpl znk>I3f!JT%3u6RQ1dBtnHBg^LgZBsBU1x=bg9Ay^%Z=*`V7#w!^1Sm`nk5?PBx&+( zUIWO9o9XKf#}{AwW(NU|`4Q9TmP!*3I;GwVJBP*>1WQAc#?V(5B7}IuhdTk`wRH7h zqTh@kUn;ZAcX<8Y;>~@43;&3qm;0M>+IcY>(GJed{u4Afehtlfahk|F2~Uc9q4335 zi_O8(7H);a-KH{~?b%b1u4jK`&Ty1DB(EGdcK?ad(?p&g(GNw^Um;`hKG`XagD?7HLJ}!h*7<^Y(mU`{DEEwL_wa_m^xj44@Yyr1 z4%isDPzA_$Fbw&BdK~fyPnH8+4>XP3qvboFH9Fp&G87$>e>pYe+nkTf*2d(;w{ca(*}u2P)f4@{a(w#djKnNA;dUgSg{Gac^;*O zFR2p-?PP_83V^+sugXOjV*JpfOBZIfX79FYf3m5Gpy=_S4PeWzPstYxH~~(7!3BvECK6_x1*v zXdiz~@%CUtxaGq{y;Cfe&BzvD6@c6Ox$=wHW3RR`B!gIw>DxVhyEj-svg#Yo{-X9> zVudNa#QK7>6dDNJ3qQ4afRt9o9L00xQaKKGRqU;S?78t+c$<+^mtf3cm!$ioe)Q8!?gXv^x9TlKqmlD%P2T$ca?ur2t9 zvfiLIptu|^L`Z9Jy2b!_5%~3#l8|N+w21()T*-J+NdO!rXHnnz_DJ3B7-|yIL(tE$ zXW)ph&cHYhugM6b2>Eg^ou^?=ZX|}FUt)pD4kZ*|v9HTW=BG7q6Y89qm}dvmOZTB= zW;TNFLs)W~$$@4U02c42%!}sos7;PB)BW44HO{V zui-ivFcTbe^URs?7DOeVKT8e~rr)E)GVkGO=F42B@gK@1W#2o%A(hXrJ^g}5w+wmZ zeJa_URS&6Z<&`nX=71ZYUF|a`!PpmzIke;GbKXK%?!EM)Yw}n71Ruq?~cR)AqAk9dtP2=+6YnC zALNI{PJgh}t^oYUVyjv{5Bc%j$kF%%O+XgkE&^Eq+IPclyXf#UthWP}7*S#n9hYA9 z=v6&7N8R%Z4?^@XnOQSBsA9dIv**)#)a4W5tRsLikHdiy2cqVm07U4%6St9o^2)NU zKIuJ1s0n6c?(O?WQ_M4fMJd;}m=#^!+#Sx@kq)1#vT$|(n6cP;CA)j6Dk$K@jeP=q zUti$+=25fU0Pv+d#Om2D>__;=+k}m;N^xpoEzLgF)oU#Hk z%+y+COmhxg5AJk#l}IHA$nRUtH($iFf-ia3uxEYJgRH zo{$!;S3%uBsJC`~zoW8M{!D`=s8=}*`r|P-&>STP9F8aX4)5if?jInejKk_Q(PIy1GN)8yP z_O~QDnbhh$wCeAjJr{_r#>%UGZ{PJUdx5bh*_xnPsORYp&@E7f#_m#tdlLK)982=( z|G=@ak&&lbh!^}ZlEQy3fp^&@o=?m8eTFSsfslZq*z!FC3OEp6X~$bYDrEGePQSjw zMG#KiO|<1_|K~y(py+jmv;5Q_XnT*+OpE&%+D674Kf(mMg$G;sd!PP`bqWUNRw+&sEwK+pSe~@U)AeZfi(=Fhi-=chpiD^^s zA_*1b;Cy2%H|U}7p*_O;Qsd#m+s6F^VD7C}Y1_SYb+8)Ob{cg@gUw+1cci{NfPy*V zpMiT%E3j8w8ZZ~R|TujrQc{LjK?7`j#045U|*MB_fw0_*z>Bsgvu;Y8fr zM^EiJ6{dGEFEP238iV+ihl&Tk5MqZZQeIhPD13A{eAWeiWDNqNt`736yiKK{C-cf6 zf1WIHazP54PTrMWr;;`C`~W~!Kq99NdacOGhtn;=NcDs%dqJD*gR|iQSuTa6mU%!;{i#TN@(spzRwJfvCB&%$enmcM=dIJlF0X>@fwMf^u za0TecRLk3OJ~xkd0~|=V`_EaaEEb70m1J?#*X8Mqo*7Gd8PGFQZF< zIbWz~_)I0M@c=sYQ3Cx6Lr1<9rrh1+mVumV`4$k$&V^$XfF+^Jg)c=_OVP18ul!DIQs5f8Vp=fTtkuP|qlByLFmvx)q^*!gqmaEs zY^pF>g|5(;Fts3}nQ*~GtQ#(&@{j2Ad4))2wE_m>qE-@>aeR9gGzNN!*5x_=yo@&^ zSQ_5$ru7HVy*s#HCR*;}8&`CurepY`>47sj*;*~=`i#|vp7K*~Yp zz>kj1y3a`x?03CQ!9+pRp$ufpbhQNkm@kOy(hA=KyY!1lbQ?OQ^B{FR?2U_NxtHbL z-UrZ#WQl^;m>9;bFnw@5(0b6=<2;4mu>Ruzfc5u89zZ)kNPuMtB-{$S-whWyxnJTS zcrVOeH~qX;%-bOm5LE#{CycBc?v#OC`Y4eE#zekFnNZaWH)99|DHongQ7O5jvQPZ@ z$Fqc z2N<_MCeVO+ku`!8sFg=c^fiKFHjpMqAI{xkpcplIJLE(cSS7mQ7!~OHM~N;ZCQx~F z0o>he{<5jAGXZXrJ{g?)-lA=S{lDLaL5-WniYWXh1%yB^NfKSbm_XXCFxzf;6>$fpZ;cf@0c`2)ncH>dF*skpd2_WvS08Cy0Mi#nIpIFrmFQE^et8JOc zjt5xJMgvM4P0$^n-wm&L0CfSwyW`y-2~>mze%CoAGJ^9^RKHpF-H!7M_170z^)tvT zGmuUnC6>N}1^fh39iWNvwsIb~nb7qy{jC;uZ^-$XuJ|$hy$uKlOo~WEB@c9!8hyYUj5BlPNc|f;0xepaFjuip1 z>y~7RaNsljGZgI{8|FF0B=py8sA&GmXz6lK^y>^he0&7Fe0U+L!{Zg7S^AZJQ8jz%|A#6rU1qq24$g z%MU|mo`$EbeFpLNvvMK{ka8ReZr;Ba{bbp~wlK|Y9I=_Fl@;0@gKpqL{Ott)%Ti=^ z(40y?Yc&DKq|eliQhusIY>Dpgy%uSIhHm$T8G&gUFJCF`YV@-7wSuYK3M z|D+S31g?YI-7}EZw^)je$3+?nhX#CN70zE1x3eby6jj*w(HtCIa2h1K1H^$6dH~%9 zN4H?hf(-xyf-f#5kzb#g##<=fHz6+t0|Yx>+Pfd@<_lX!aDxR_M^apr9qIHhF2xp{ zMR0yz{m~mC;C#Th#688^m2mja6Ekrv-e%wmriZC2WDU`mYw^Ro)7#R%YAC z{M6b35(D1w2hZq;d!`csL-R+UfrUwyn2b!vG@Ih1M;pdX_1&bRnP0?)2t^^Zc|y69 zBqr~Ar$DzTp$n`BpyTOm3H|}!ZgUbHK{5W2>)t0Zdb5>vdu9UBS2Lj6qD{2ye@SSv|G zoA^5s@(koJ73hG}Uwh&H8M%buj}>il|*>p?f=5pF2~deKz7E`Z*@%+*X)P zcatgDG|3X|5j&V>FZ|1L$B6-a`yequ@Xfyx0|r)qY&`ov-2e{KKsJy`M;3qW^KquY zBK7@$WeU6k4$*&leQVQcc;E~o*O0B z0~g;q2Nw?I!8u;=FDlSv73iJ}&Ld-tsstMDIMG1%oD6jnT$9VsN-PYVm4Cb2tXEx0 z1B-l;krs6uI&4M_e3qX>f#*T7<#%a;H4yWaVvADRJ7xy#E*aMZ936BP&_SdpbdUj~ z5&UMTO?N;5#`o;j#7Buocf5fw-1&6KS2p?ew4MSc!mi+eaS>!;Uc4_Pt-|=9UTg*E zm9_<&vuXZrz$2jnc)Fz3A_15VLV*AaO#y=lvIGG_5}daI2Fl zaGJWMV`X_Bpc1moCdaPa4tIhG!kbJWJ0@A#*&sW5vliqfBsPW~<5*V4Exd(47l)?+ zW~(|8@H-u+XnI<@wvVm8P2q6tI=JFWa+27YVDkdzkfal3s}~!DC5=D99DlGD(aQ`Z z3pgdXZZ-)nGkK3p{;WsYQh(38p@>9?Uj4L4dH)0-EhS5g!@d7rlOkS`UusZexmzl@ zgNr3UDV5lKs)I4>TpYF;Q+zn@p0JC{eW3jxxeunPk_FE&A0#M3{#+(QaoyuZ|KKhGs99r&p|H#93GYFd!=%;FU#K?b5B2-b*bjK&Nz2J2{6g}hSx1p&E|S|PsAjXEP)Qj&;e)& zREfaClqo=_Y@R^e;djp7Hn%=mp=~)U0BI8WA_;IAJ?136%6QDjw26B* z5~DZa>O2WNNS=S_likD%QI1^2^;|Xp{U?NIa)$#Nh;i2-&-c^gOo_^)eXd(}-n!aX zEz?wGm%5=81jk$kWCCc(M{lo?65^*^|cw-kC>63nE;wZ@2Xc9*|CFFEJA?>#I^kK6|zX`}Jirqbs|26nVNT8>{ z2~m=v^YBwUmHK<0PdX(PyG=KLX4lmmtc+dxLRV@?LiYJCAQFo!@ofZ%2IrX#$eI5K z4~EOc`WFwDQ1;gNq1OKObpl3gQ{SOKaYf?h)8`YzLLvEV5iSNcy^6<`!HQ63f!LXo(E)c*!xW3-5SET5!@eilK?!e-MPSIx1s2@ zv8)b6O?C!#al!cR4~}MXx-jS(D~vt*6%PIb9JM*%KlxTw63nY38#_jAx275R1GIk_mUV^-JPgh1|HV~G&0;2o2=VGO-lC$MP?3GZ*Z3= z1s~b{a7u|?t$GkUFZ(*TQP*Nn|6nDf7if;1=(FL%@od6>Y7SuBIz8hd(lN)ZW59PD z>*!LI5He9bb6UHHaSskiK6k&(Q!U2f?fhd=gBP|T zq7gCiJzs+tmjq-hAolVkGKH+7T$-@p?dK5pxcy4W!l#}Owch)RgtrYQI$XXxX`u|w zi7M}0qXSt!v(?qC%F%Y!E7=!R7&GI(P2FDY$nB7eE~#?9Y@O~{=I8*bLwZ%+yzRo9 z$#;*BY50sDKK~D5K>2CB3`pm>-XBw=X*v*v*U{bAP_HWS6TIV|IBp28x2h ziXhRV^EHs52&Ky=NIC$CKf|Ms%1q;#h&7+p=c=Kj77xQ|FGs(R^#`XPftg7Zd{5p# z!HEAy4(NDG$q=1O6<6%=9ei5Q&l0}Yvbd)k8QkuF#Ap-G6m(MiLCc6B@}EW?b$TV_ zE;5|cWGueR$7t2}tlrcuWdnV4HJk+XgFrMM4)SzB4us(k0T$TsxFUYRVNtH~m!+3E z6cz)ryEX~ohpVll-yQa}*Y=5o=zI=Y&C}}7F6V&S4y9jY_u>T46D_N!7#=>_{Lx_V zzuwtHd}(q6#ar)swW}y%UP$a3w8W8bcmlfyf1I5-!R+hbOpdNcVp(8{&E&4=`d6uC zBfsW3d~C>&wsM#rs2f3a$(rylFn_k}P=;u*+PDMZLi^pQ-uNsD(vGHjT~XJKvB+5- z;}ccgVf?h4Zn`sL?a6%wn4yxn+c{F#>xeC)(UOi_AUSm3hzaa6f9t;Te`Q0fv*~34O()6Jd7tScI z^p1Fm88aFvc@jJlvFz+;W*bcy6u2hFoVcB1rHIx(C~^8Sb~VnD1$hbG5`?+IzqU}L>tT%viUD-QL)9iqI z(D~P&^<6;C5j(PPiFsziVnd;@E(DTBy~ihk+c%eRYfX!0-6mwSzMH@0Q86ZbF+Cd9 zl}m~Yv$iJZ2RRS(GG(@$FlDaWIX`wxreGDft1@qpfLf&bwZ6GC$QwJ+ZE&H&0uw0& zBXlpUjlcX2R`!vfD$6`Juo{mqd$=BDbY=&r_iF>IsCI(|<WCrnidIqOy!fPd zr4d5DLvyabld-Rtb0ef7yZuphD&8L7Z8SdEJ=pN?$bS0J_b;rkmf7yOl_eJGAiRDkb)wys37fo%atUYhs(=CpveX63y^h@KuIp=Ub%WeveWCzss83 zscFrv)DRVx*qqxzp!o*u2j0ZAMRbs|j|sx`GDFbRkO=kD;8LSE`Ys?la#Znq=EfAs zP<|Oowr_?SIAi)U zQA1<+MhbIB?0ZY&LH5cZY#_~vMJd@}MdM_){);;O2gk;i@mfW@nP+Gm?b+Cn&thWj zY6|T6YJ972Q)jOB+SG?dCJ-z0#J=4dSgB=was4uE5+tpG8NO=A23FziE&1)mF2}Pc z=;){cV> z&8l?VK}`R5q%6a6iI_!PuK+wZsf#lfi5Wg5D#bS)u`gs5rS3c{`gnmKCDKaS{>wT6 zT~bX1+}m_$jXW-=(f2Iy4t4h^E%4C|h2wRdVKS`(iP!D8>s+o0dr&7N$lIHAu6$ol zxWA!tU%E*kG0mok3plgKF2EyWR@h|;{5pBc(uANrjF_enO&WC+D|P41;LI%1cWDX0 zCNHT=^LUHCn}!cJlg9wpsxS;1c8kS`ivW4|wLx5nbzI_;jpt1kG9Yy_M_aSpW zeYFzj?q?rOSHTus@+0n9C#@Jdv^lN$Y`6uPs=|IcIfALJpBd6BbMw!%(0`nMnK{iS z&q6mr;5ao6cgiMzAb-(Q)XUel`>+3c`z*cl-Ljvfov2`T#^(zl{E=;iR1?Tf*Uc?d zqohTNOiU_)Oil8W&EYTyXCsxZWYAM_y`~pIn=Y`VWi8;(zo_ND1|HzI?!vi1 zD222^L69o{Ca&Nve9{oEi_)uM5JHvo7qu%9?->E*frCE|vv2{@z>i!rR32Ex7p0XP z9N#;g7NQb@a7Ag6tXgT#5o>|(7vYsHNYi8g`1b>2a(bk(is{Tp^Fw|YG+W|qRWD0U zn$u4uj({W7S-3>-?l4^kVdfiAFHZ}GBj&J`Xi=q!Nx8z6-T|U_#A>Lq>f%z z?CIl#(1_Ehik2T~OouiFR?4*^fw*KroQebOOeP6aZk{=063xAjDK%zHd*^?+CwiNb zg+2ay@cUL1Yw)~*qI#Mz9G(bG53thd1l(PK6N|8baU`bH|7ORINADe{!BsG?A` z3#PL=a66?Llym9o?S;8PF1^F{oheW=QeJD2TG3l2hrlnLB!Gfc!aAQ|mgB@w{fbd2 zB;?MY^ixi=3Jpv{4udiu9`iI{1rSbnHUO{y?|!*#HEs2?ydQBIE8D6h@p|iKGz{%A5X)df=t^x zAk!AabaHi02Z|r&Z+8$t%78@z$;SE^xiuOuPmMs24~DjE-IT|p(x$$J69z`9us z=3Vjt3#ZWM906TnfuVze1<>20l*6B_k@-1uT||M#kf3IJKeuw7>H>=Rdn)xhc-H;J zGz%t~P3(|qbj~9CaWXI%8~D!!O@uVMwA<_%6MuT+r1`>Odiu1qS1$KyO`d2WTWuqH z6O4zZ@nupH}&H3KqS0v|Om*I4+VE>#Hf_nYt(yA?YS3 zf#yim+}$+iw+ZcTu_X;@HZH2i3=B|oH(uR@UG^l7s!>Rsw{JI#*Bi?WO##)L>`PkT zI7k;yi@tM-EvZjSZk4+XTT-Ym0lBnX;Lm$Tn!|gP1A`4gM#`zQOBmWu1U;W@p|#;! z9FwN>y3tDS6;wea;+dVeJ~nF6Z7Td_0`V(s-m7EnUsJZhT0!_NFJHJXXu+;Y%A9m+ zVL|CdjhaMdd*fxY$V8zMqKB<3Ikbp0XZnbnHvamRpYL3TSzkU;Su5DUB|9DQ`o_8_ zlA|lT#ih~1Ll0!T7GhP$t*p6|%<0uo{gq#fataDBR>y|8ryFm*@f;%lqoc9b)9@5s zCKR#f#J#sir_4lZQN}qd>aw%J4S&i>7gm&BxSK~<9VR~}eyr(wjSXE-c(O{kwpK9~ zFT|C7rN2`(+pemg7NXgx1Wy$}ot0o}oB^{;xX++CWbn5c&Mbgt-^?Z37)WdxU(2ML zOQ^1o-gCv5=C|X%4pRVG%-;o~tei{xUKRVagtZIvd?8*@=T;{PSyc~(I$Xvv17ABd z5YmYIgQ!8EY_A!)h*tnIi4)CK=N+iH zuBF+m=!}fangrrX4FD^H&t8INMc1rXzgF|h<@qvsRf9?qel3T$vif6a6?~6}Au;}| z%IB8YMtk>Se!Z3?Y`AwJQ@=3v{{NrKGTPai#JulAab4ihu4 zYiH2J!&Lc92esmD9H^|$-(=cADRkwjU2=yHVBz^@BBK={U_GrgJKn~7>^-7Gvoim7 zDS&tSqvf5(c!Q?cwdE8LO+u=AY+61^)i}q9D@QG5<|vZ9xYj#0euWwk*&Odjm>Y}8 zjyi8L*LbMT>C6@qSPW`}LOXv8%LVbRAPwX&PpN!{3Tg2v)fIh|MRjIfLdi3h)R`3J zF%<|btIKu`y=3KD(u!A1owG4H$mv!1Q9a{9g=W<`@sqBELGz0%pn9?VIdpo-u415; zRY=3zzTsf8`~b&G(lbwOlZnzash-s7zRgM240mm54}cLT4ppx`V|qPRVJ(c-r9;zie-DNdx^kO|ENL+|&6w9(z0Z1V zXN>~v;~JXy73fY2Jxhh^p^;+9E##3?(9t;(LF-(I_&p^!}Ev!Bu)I9#Dt{(z*d&9gj9e zd_&Mp*Y`Zyr`q<*Uu_R1UD$7(AAKNeplLIhe}+WSZPvA&p&Mge>sBOu-?Hb~D0z9~ zyY#p>G$nTrrR0%Mn57Z%ppFN(-Q;HBOQfnVNjqAo3qFMiQD?>OHgji zkh_l9S-o9h0SY={2-7bzsG^7{86!~|J8`lvk<^K;9c|HUBW1?Stwon$AxNyOSuCy? zBTteu)Cr+gPO%Bn(${D6TRYqwQ^!Dx`KeQ^2MVhQ~t*+|Amx{M53b}wTT?eIF0cSy0_HKD7w0A{%-@cg9&En1U z$W`e;w`=0L4;10{hm(fyNVwWT_W9J5Ac#rYCAQ&;o0F+D7gM{%xxnGUvW}*tE$nHADLQj+>&ahjLAFI@-C0* zGsgN-B(jUKY2o4qWlXG+Tky18KUr^vjrCv{uC6N}49biKrFs(%oUqTfk#$P%g%bJz;N31O0D>-1bivZ(o-{oj6Bn)aK~SOt()p>pSZ&AP8tTX6%`Z;0krp;9_I$z^Ua34u2cd(YWDziC6UL4Vn30t7+}X6vEB zWMNfITVK{LV_#kIIZV!M(^oROgTwECC;?*x+fxIVYy)EP@W^y44>kjG8NcPsIc6oJg^p0tFh`K=>pg;cMc>n{@gOy#X`w6OyKe`UqfK-2(8wx*) z>y!y*C#W)8GCIT=bGc!2-fqF4=2gSRUIqwY9LagbTQDTeqaKXR%zf9*R%N;zLc#Jv zamyP9wVi_}xu$^(%g15~*WG!Md!X>!_6E2aA#LWI8PmE(M^AluqjFRvtbw%gIOGa9 zMbk6it?#I*q8QdAHI$ETVEPdoQmXX4T6VF+M}XRcorSy^BrpD@!1S7t-=M*iF86ca zR+BcWaD4;h{O0Xmcm8u>dC4^Oq%t&0nVKHSu2*G(?8LvX5O^t(zFf0VcjEqRW+2A0dcouXZmt zve&C8odYF~me%B_#(W%Gxe6+sEf&>JkCK`V~g$YT$;&C(e<%By$i8P5^;wV5+cn_?=acQ)Myl^NtYij>TR(8DM4 zTqFb__+UOf!T9BpsEsIX^m{=2)*;(^&8wrOXAYjE9UsDz(>S4o5JvgR?lXDz6HbkP zckq$(a1-%+!HAmVnn%Ne5rWmPxt?2nn(1UXXW=t9*%DuBP)5%NUgB^dK14hwn|GHl zvDiayZZ7DfXncLb>uj~IgE3c8+3Qtny{}c$j|M&hKIm9YO$RUlwl`&6kggu382#S; z61qL9+aYE2hplJ2E7F6rxA^raNs^xKB|YbE!sMbOM zF(R=|$KZi`A6cT$1e4tD1@^QTmbE0Z@SIwO2=Eq)qeUOh&g^z^P%3FYTpqgZKRr`a z>bP$DL)GzYYUC!>FQYpcOCRjOdcp^d+HIK{g4D`Nwr>39Q|}g*ljaO4J}Bg zo9j7Z$q47WCT?Ndr_0$<(&!mW%JAx!p5e9#Mn#l1T!?p7fbCXQaAWVH>V~=(L&)DE ze~#4@Bi1lN@Q$fNgI^X~ANNL9t@ifQNvh*Pc&X^imF7Q4E5T0lCH+_S zutz6hJP;+Hoq@D$$oH2<3vLqOH`vi#BOa_ty22Yd`m#5zYb&#l@ zqt89Rd~@j$I{d&{!XLA zt7iSMvwOAom5kMg;JJfl{8SJErV0AgL0wevV4A8td7*GrC7VGr#msZXTj?qu` zJ(DdL2r-d-47&v!^JA{3^SdL}+Si3lvZI+BI_|55|9Wdh#$5G(J;8qKMmMaJv8epopYi3_uXm&bvBMTCQU z2=OO?we!_B=r`oBya~`#*PgZ=L#>iDCiIwJfg=>JcNQaV&|&Su59cmm7hnn)+KY$P zKA?nV>jKt*{Tw0w{+yuNhX+@u1yc$ArS5jsh}Gt%rOqm2JdZp-KG-!>TJy|=Bc5M| zQAh$?O!#URzO8#)Tl(W)FD?Qp27mHB|KGngBChWEO%b%l|CcvKeEIZ0-V`zLEc;#u z+iX2gTYzp1dFc(Pt&zlVombfvyNwAw{QpsAL*(@zWj4ZR1&B8$X#S&d_|Bev(!bxE z=XELs_*{1HIW0gmKTE;(zLM&{pY&qSo&?v6iJ>trl^eVQZ1a5V^BeUo2yJ2lnQkaCD$PpxkRZrxoc6`)?62padPBzqLp$NWl56BwF#|q8M(w3Yc7)} zo6L1HX3f5zIp1$*R*&D`zy0yq=ka;G->=W>@_fDCuYKO1*K10e63hXT#q*Tf-DN_O zuYYSP@fso4UT<+n`+r+XeEr-J_~4sD#BNTEIE%0ny{7cYSJkS`q%1&kixo z@y{Gg0XDK@Ixb=6%z!o-qIPtZfiIj@4Spa5ak`;5_R0$?`Mf;$X6;C^p-yz27C2)o zq3?!$zUDo+9pVzuX$2co<(^8bG0vY$)6qM3_(!Uv&jU}&MHOmgG%!aFawnl6pYQN` ztT)+!d|TJ@j&7}zV5uy{Q>S3WX7`U&Vq6V8nEt2b#Ng`!QWhQ+*KxexcL!eaYT3s)uFV$XV zl;bqT?;Es>VdwG}+zM`F^6So(c$@=>_I*z@ohc_mD9}qVkwOS}@K&4$dj2(vdj3&V zGjSxP=hzj?-qyl0sI0{efy)c{u0w2(0fGyn>4^mOg?0-S0+I~Ev&cNT{T z$%|udq{(sBMepZ&f&wB~U_|gKqZRH`YfF%o;KQMx9h?Vj@SZczNI}oaj0!`CQFX>) z4z!2awAJ34X@_s`1!g%&&dO#7vzBI=>j(;DUEXzg^l$9mgUY@9h+cPbMm_7un=26# za{#wY#gEW`2cC`Z5e%2S05Tf%JR}RQ`1j!0 zM}IFpJl>8RUJ;9=u@KH#l?JGJ#=)M2i}2n4yV)l+ri)%=0h&a zu!c)3W=03)`j|(RWW9UCb-}yV(`vd)>qh21;yLN-#JTJ|)cO#7cGayhqnq13P9!B$ zHPd#zY^r8c1MvZZOn4{_5}}N8#C+p#iBtb%P>1w6=;Vh32;1j*#%P#%acxxl0fbs# zk9Sx!y;DO~oGXC8JDi|(>M?>e{x4+%Y_iu!^IotTZeTA(nfSmKB`!WdzG?i|Eml?B zJhHtRg4;qL_55hQFg(rFmd1r6AJ{HPjvfU@d)|4QrkFQ}+*WPVB2Yh>tbGqOicL^J zU3l>Au%&?bO3KBOX7{+#Lc;G6-{uv7v*GBR~ z+n|{^db3G0U)C}1V&L63hT{}i7W)@t)Hw+?@3h14Wtxd*{j!WW=rJ#-v%IB*^iE^J zF;cu&!FxI>wO1{|afadWpGo!d;(|X&NF}3I1dN!k{y5e+)qd@$+a9&(6AtCz53!)d zf6=;hmffSFVl{C%Zc3qcGP zWpF@!Hx_M$IrFdm05R~OgV@ajH(z*g!%l~`RW?N>;kqCPJfZy;x*)FNirI;?eLZWn zP7l(O15FxRnh+B(kU`u1PGtt-JH9u!}~#cmw3 z@NmfpEiN4kyM~|K?j>$dKr6xEt4w0;t;U4lo^%jZ0(jRwAPgx{Q!%MCT5`G9+XO+2 z`|Sf#dRi>ypEILZp(RX!M;!)PYyM?f4;_Gc3~$p$%}e5hfv0!>pE^-5J=Pw%=iEN@wrJKor?LCJj4lLL~3PIeD{QEKK> zV3@}j>HthPFsHibeI=JO6}OzV&lR9(z=Pq1pAUJHk{{XcLG@Z!E8zrte-wZIFu=hJ z8OX9~eB`iuYf&XLa}J1X68zbr$j2{=0_JI=XsB5**hZkH04`gG zV!J3{LS$nNYM=vs>FPerNN^Dh5PS-^~KwZX8K*_;Hr-A$+(u~3aI3<^m} z;KQoKUu{7GQJ`F;r* z`fWJ#lP}3|CY?P8eezzPKd#uX#&G$PUdK5d27lWaq*HL@2T6>Eut#kT zB5C0bsXANdUMqE^WBL_C);2&fGr-4NNtpMptjH(5cz<55a606*_k85cD(t6Dh`EI3 z$Xw%aDgAv>A==OC9-R@~H=Byg-@G_G>oOy2(dvz>nN+NGX?3nNG)@Gyh?^bAs2+A{ zbV;2J;I;<(<}S{CScg{mdWCmOE5I+Y;AIlp+oO$|>%H4upI7?+dM9MRMEtHm?EqQ* z9a%nTo}>A9{bMDBxAu_1G0mM1} zZ-NJ$o#Ccmkka3(>OZ8_|ET(M2a6xN(JSq#1K%$(K~?WjMx&msJUGu1n-C+;Y;ri} z`l|KiceI2&-P5f$Ky%j>W}^QHSh(->63T7xDnCnP)x3=(969|Z9URlgqVx?3tNZ{L z1>W3*p-oWC;Hx0CxXNynfT}0>@+OO8L^3Q(z>9Mo?jO#vX<=bAsS~`5!eiyZ)86w_ z#~Ss2&h(E`uHV5tD4#3tAC2cRr&g{n-}~0*k_vUz?EG9eLN7zWc2Qy;Jbp35i-xp} zAcy9sJ|DF7xyAd;e2_pGv%d;j#O+y)nyGk+})jPW3{T{K`$A3q^Czzlig z38Pik-4C_RlL532&>3OPCVg_8v{hNP+^b~4yV6>uNbHVwji^aiO{6KSy2h8wYYcLM zMS>z6?gh<6A&tx_k#|G7Sl#DmknrM z(2Sn*pHXSNy{8mX<=dakwdpSIT|hraZ!P+xj%&S*Y=l^_`i{;yi&ze9T(!^4$PCGL zD%%?{6o!wY!D6=cR|T4HT8t(YmcCy-cXe&Xm70aU4-FGV_O$?UCpZdw(|=R}QM z(N=87^~@kEQ)7HVvG&V;9Ep6qKj1(tr>`~|rZ%baZiiF#g{tWbG;hzfFnU)xI7w4t zLASSl1_2S3RmsVBbUbX;1ZItdmvAW z#*j6n`qrnzA=MeD3KF(1hX4>*E4UC*wghx9Qx|aFyCY7Aan`<9{{vJ&r*i-R diff --git a/third_party/test/golden_widget/flutter_logo.asset.png b/third_party/test/golden_widget/flutter_logo.asset.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..fc9ffa27529c1c7d62c7faecff5822448e6a262e 100644 GIT binary patch literal 10130 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 literal 10330 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.memory.png b/third_party/test/golden_widget/flutter_logo.memory.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..fc9ffa27529c1c7d62c7faecff5822448e6a262e 100644 GIT binary patch literal 10130 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 literal 10330 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.network.png b/third_party/test/golden_widget/flutter_logo.network.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..fc9ffa27529c1c7d62c7faecff5822448e6a262e 100644 GIT binary patch literal 10130 zcmcI~i$7HB_y3+TW$R`SLZ#+HqLU(&#F(aGCf@iXCgCbEXVYQxc# z?#6!;ymklI%i8<9tZfV5T8mmxy2i#>_e_;jI*$&YplVQWY&-Xtec{4M^-8+uHtc9q zw*AgoJO9cb4NU#O670AA519u1K%NLWyXkjs5>=;rs-g3?Of=)~o`4+{{SHT*1|8f} z{j0uMylB_XHL0z==fBJT^S$Qa{rVJO^?&&%e%&8TL0;Zi9@4hEIR05@^FZ)i!;Ce> zgCz%={9KzaQ1)R=WP`mBJ1bB3qtZkRqm+3nj1627;yhQj%C;rK4#kk0Y!13c=uD?j zxu&IxtSIG$+FT?nT+Y;ytvW$Nkup_=Scj99h)~kKTOuT-iZfN2h#Coc2te5cD3gom z#o>J@`tt$lR|3fle|wU6YYa%%7>@J-rBF*g5S{WR2*u+iq3UKQLJZvqd@XwrfgG4h zu?5kL5O488)FVX)5H(5B8bp*79YqM1N*J3%XCh)<+^v#lVE0$j*i7I>!tTXYV+qyG z5CI+?=f#`@?Ifz#d@h2n!ow!&g8q+*2&B&hXLk@#FK2`50fM*pIf#n}L7-r*2zj{z zkE?THzJBv`VQV0*rRG7$2GA;m`?m{9tiI5Gp1kyqj z6a7UZO{Y+u>4aN1Ap#4@xE`jV+(`tJECAIbLF)i?5((-Hpw0y71^`tfKoMM%oDE$N zph<+&B7M-r2u(u)XmWA$h&rq%g$4KsBKE+9LV$`qK@1~;B2vZQlHyGKEr~T#3Eq;T zDgKsN2O?AaEh$ciw;u@F9;>M|rXk^0eKD$r=J# z1p*a?mA)6|1q3-9oY_kDFQK6&CkZZ0GYU1IB%q0as7v(HguNtxGAUvpvPn@BL@FsV zDOA4+Q4hpv7YppF5vqET2&JAJ@e{zCn7POl9j@pz z8LcZc)Y+8OyogY4&L`%^2~{Td92r6?m6k=$tqpL3Y$PW^G>WCqCc@%8i$dK%>@>(i z0Bs>buK}nD0h$G%(In_O0F5U=!T&@75h`1KB`lqs4J8x`RgG9~$VC=c#3md;1Ssb5 zmFOgbz1+~7Fk0e5rD-lA@ISbL2pc`@Ss(ZyY7wHxd=N?hJ$8afM$N+jL>j5Ek4i(G z2nzKOARe&}kY&1DQ9fxb7sc@N17JP&fGWwh93pUq_bOFp36C7c4@%evl;n+4X%|UeYO6(vBB^>6cwf`uz#f9A!5-EUaj{g98&5+w zkRIxtN5Y~>d}~#vvp$J*luBC&ePD;%uu8<;Nh0~8SXLzAmNT59=g7F;)aIsBNw?3@ zP&E=X3qZq3(2W49M}i)w(x#B0aDb?hv%w<`G)bo&=uBtQ5zz|JBxggu2nh=#Czcye zR3ailwN{HtxTKiE6_p^Qcnic566=;N=uU{MKzBl11G=QRmn-7>5wwvxDol(VtrB$_ zN+Z`ILf-F^KVj?0e+^ICQ-+`Do>9BZ?lg_?m zQ>d22l1IFgkg$0qfdC*NB>~LY-1OBXm$@p;m*jCKidDioCSa9mXu$;R0xE6G1gtiN zYCytv0IWI*O9QgTBv~d6^&(ZVNF>aGv=vTgO2SC8Tq^B<6YYsen88GUU9QIjmnTYC zJxQPhK{2-kqE`tQ#0XLpff!GUB_I;8@nx4d!{3+O*z;!0vH1<9_L<|ucjL{8pEopX zAk{=XH$Upkcro7F)6=7voLDs&Y+z_DbT-julDo3@=?J-IT$y70`_YmEjbFbE7opw> zNZ5RwecYl_#Z^(tH zxmiT!OWLMPMX{U2ye5s6s8Ge^X1_U7Ib4O|H;uxp{!e$aFyso64GYv;BGOA0VS+mo z`{{)BO(vg5s0bk5#TYPeJ*L}m_0F%uo?;9VFJBk%_$Xwq6VDV1PX^EQAI~fbZzdnT z{Ih)$g=Y%SKilVnJA4#URIso=@imPQ+3H5|9n{Vo8h~&qN`& ztDvD9Ratu-g`~Uq@~DGnhab=OFckEslS?PuD}Y7Ip+EiW=d**TM2-G5>c=xInG!Af zQ2jH>^rg%n-h`_%CGqGiCHDsfy9%bqa z3p8qbdRCSxK8aM;gP^2FN*sPP9H~kfx+gpOJyvFBSwHx#gd?L&S~_X!@m=Px)j>y5 z7GLx40AslGXbR`GN$0o6J2daBGMpiYqeM!kgJtznsTjTD)S@s2qKDG&PL{=&8Oe-T zyp9OD=&2Hh^2N8fLa#eKp+hA0P=}KanOHcTC507oi_TDGix)>KXMrOkemS*8`}Fh{ zPoDUtu8cC1&cqVYBsS-6J)5J;NB3b2JV^_SlIU=jKF9E$DW!@VY~c{uD1eZ&J#hnv zKue!ORdC)Z25ws-<6t%}12ve(+zm5XU_iYU4CE`xD3He)GB@&}>(vPPMT~W8wGg4w zPG0XoVg3YY;s!QGD#O9e^^ioL!DR8)%D7u*v2p~mbj_@*Y`)N|ny{))XOzH2P+=1v zw@Sq$@@ujjiN%4Ztl-R>Ql_fUZ$U81)2Bt_;EbN^}&$y^-mh<&0a<^n;K{ zmPRS#8RHanHV?*g5>8J4v>bV@%T4!tY=gT`klTqdN^Bq}Nxy*muZENJsxMW{hYQEK z4iloQ6uQoWq1kIK;#!+W;eJiR37@nU!gZJFoU}MB2XJB;ThwsFveC@RyT0JK|}Lj&9Ume*KDglUv|e* z79WE?$5ru5l`5klN@7u}`117Sq9sVWS4+msH>Qrm*JNhFw|#01g54`1HA-I&x3>8$ z85`MN{w)f4A;CLL-XTUer^%7y3%HQ9FfOaGa#R^yNE(^ivg)byLrY~8F_bKp(ix9c zSbs+;<9RM53+O7b)_jf#?*Ap{O9guDHi;bJk+(Az33=1>?5UuIyS6TBpPg;l{2rY!SE?MYr)maNoY8q=wu7`v}CzQ7>b+v z4Q^FiS|U9AXR%ro^uVv1IvlrE47{lYn#@}wOat(yEV!XV`K+F+fj2=mg5T;43W%m? zXkv28(_>&-bD=EZY$01^vjX>cqY9G?XT3o=9fvqiT=2ZBm*EgM0Ub(IGxnO zBsQFH$Vt{Ut<*EszqV^|=tyx(<(Dyy(QR|Ni>NfcSoDhhX#pqsadGlGJJ4~oyAkMq z^hM=?kT{fb6A;)@*u$^y6XH1Xw$US%F~ZEp9hxyNwGIN?gyjB~p#33zBTaQL>Zqk~ z`}!>kd)xp1$h_^GZr=dSc|kHGyKJ8UtFfA(14Z4V#qVl&D&Q42YgJak#|H=8Lprjx zwHc1S$-397clen&`WyDf>r&3@(hqe9FE9Q_;Y(NhXUZ^K&sw6eL&tmGU0@vlTw^)z z@#%?fcbu@osc?2>nN;uEtIUJGE_Q`qLa(6|{Gz`Qj*O!Nq;{jftXeDfXy!WKnjKya zPK9rSnwkubEaB){)r`0gy;dH**Hfe*8iOI9%@*&o7|A`wczCGuc7xpP?z@ftX1#Y9 z>{@Nc`j7F?64HJXepBAB!s1%P_{^j~)m48c9ZQb0F5KSjSZL>CZvM>pzzg4Jg`s}6 zdCg-hw+ojb!BAE>%t!yNKOOf%YjdB`{G`h9cwLCwT}Y?@vYSkUFU zwKW_F>Hhdj+DJun+A+UFk`M1!FcRqTqYE6%q~_qPyKc9jJg>R4*ghR!xvA){Z|}<8 z3O-m=GL~L^?bdhjY-8iQB~7|KQ7=@sba?fBUCWCHzMivBOO1(prR8wPcScjHSgOOR zx$Do_bxVtp@M1q7b)E-xAt&*x?uKIdUw=Be55Ia}E^Sh3_X&A2)OIE=S3M*=Rn_qp^V>m4n0Tk0-8D;xJN(DaW4}7GdASon$UPV zIjQls?$(|vi0ovWA|KbkOY@tVkou?9n!uSS@s$g*Y#A_d+%xUOa)CSu-pR8 zk4br##-TWr>zkvpk9M}<{_!8tH9O7d&ar+?l5_}+ibNo!^A zL2Pa<{j5v!`^DO2(kHGnStW3Z6q&-|J>2=G*srTx`s8VE=cM+8bZ?pD$u@9T2i$dJ zd%1-SmySP#;FM`Id`!%RL7yMRHN?jy%$U`+9M9DZ)j&^y?WGygTRJXm`zst`sJ|&l zo4Ek?1T{-Sg$63C**gDAvyipNZF?}Tns+HU;O?i474N%!ceQ!;7Gz_aXEThVFs3<7 zhDmglTBmsOW@(JV3ogD8nx$oKj*%R~Rv zgoZYLZxvJxUTo-Icn#L+{wG6*kr;C!eyE~RAEj}NBja={`O*qr-!9+ex+(2K{?@*O zDs(CzCc#oVYjjwap=<#_(zs^=bBjjdq1OWc{O%sFRl{u?`VJ8`t081(__kId-#Zj= zKU$?r%$l2Beox{wTFkYvjlvToku6?-WoK@+D*8SoNGtl{X|JC0BGs4U-|@l0&!O0A zPY0o<2WnIKw#!2ThWg?-!JWmUjST|j7ei(iUVgrRZM?U)tu@Pquu2E3=OZP7qa7dZ zL33OhTPp1;$jQzPtgXIhdH#gJ?$3s9-|cK#$0f)+;!z*z4q-)%&}9AA?(5ctI~-G& z&t(UtnZ3#lTt1&C;y~QaM@b%q^nV=%v}Qqji>JA{x&v&1HLo@mj(l-dXS9y$?{0mS zX)^CLmJXjv;Nqea$KV8vXE;?#rB@qopI>Zd<&)FcTfvvcD@SALL7=0}_F8Er>?jiC zy&qg45O6+eoL^$up3#*XxO=YZ+&(@^l(Sj%yGe|Y?j~vKSeGF7_K@wVjCsaWD=+Pw zT6JOcV+letxa2D`SH zWi@=Mk0q6=R~tErk-1PSw!~ODLr+}49P7${5#qIsqr3j5O@eCWgD-K zhl%u3n|`-mx#;*CPp9C4;(1Ad_w|-0n^<*!?g;NYwz|ICce$z05evIF&ocHu^-M-7 zMA=`Lw<~!3m$YMD&x5QU!A|TQO7rr)Gt}=btysb6EPpp*wRz8*qTI#;4J}vcjhdd2 zqy08w!~lGOOP6Ky_+Pu{1$}NBijNx&HMzGwCwZuIQ?25R#YurPjX2MI5^u*Gsi~87 z2JCy35UAalY>mDQ=jI(k4(C|%#(MuwJO2H7(3reDybt!Y*jwK&TI@UL<9e{gGiAVL z#g5r&YnH?~-Pq%^;MKQEj75CLkZjRz3vwT8YjtWIk%qRHE8>T6m!32pU19d|yK|{( z)!^0Efa3>++u`4`?e;fXY@`-+suwJx@N5HK(cm>mJ6>4|T0M9Do|BZlDPi?wjqylq zj%urkooj7pe~Wy$|EYXur?0tXO2@?oJiN%q<=*F)4;J-DNz)#+7gv-?y@DDWPJD7q zUSyVL(cR|b8k{@yM{?D5jhgA5LjkLg>tBw!f7^2on^vAKapjA86X&s-M_U%m3+?S0 zlG`fQ=FF%Xax?ko=8DG)d!pav;o|P=m#d0GZtzjO?1;H# z(|a42jCHm;H3dtb#>XX3 z;QoW#=kkor*tB{PLeY%8A}Bvn{8hG~DELixXwaDKc|lHr-`l#YlRo{ep3;8*UCNpz zJ&!C#zrR|NsS&u}&h^rT=|>cEmH}T!*oC<#XR}VXdIlaGs!pi9k-FTtx4J33?{UW; z`q0Cmb7+02!S=b^)1K`=w?LIuGW+|w870VL*`F^S8(jMoTa@QHvrlH!@Z0aRx-+Z2 z6O(r>FkL^sR`E;RKS4@C|4cFzKe?Xh(($7YgZx232%Z~;u>rQ=Ww0-4aR(I?o z_JMQp*auCB(Fe9o`CYkf_L@rXL>uYa!naA6LQI#J`Nkk?DzgiMhItPIhyU?8(tdJB zh`~+RQQ?};rLe8b@5ri6jJ25wp*Nn77(cnAp*K~)QI8395J;0w`waG%6$E|eEh(Pd z1%ZXSNIFJmw`IyNo)KwnKUy?CuuZgR?vNYCY`vFfSGapeYM_&QSL@c@v*^?c*b63g z8uK}ehQ_)eMUq*Jd5>jsleP#;ZVTay6@qAorASW zefrx&?PsS2@3dPPm_K_FoeJNzoo_8>do@C$6Ui|*@AeIOa?Jk|Z+5fa9=j!ln*$R0 zV(vGH!jrdWB#tefU%pg7g;?pC-pF&ReDEgo)5)#1@>k#XZCgf<#IoROr?+hm{jQHN zGcneo(06T`edU9#F8)0SGCx(sz-7jNc*O}7ma{?LS7c`SEY`bHX_M3@yJ5wpz{QW2 z#Z(n9yLRv1?!%FB(ExVV^_a-6EmD$e!?D?2)A2pmr~Q4dPe9M>M3;nT{#M2EED0L+ z`RFyptny{_yVc=+musQ5&S$rk#Q@dw%PIK>5gK;$=zYbk3SIi${lc!4!uj1Pp@-i- zklhb@*KyrO=m)!7-PdSk=PQTVUUhQK%Z2kVn-6|AF%RA28(7t4xki{jgHGM}^`^3O z_C|a}H7`HDxOV&ZYbNI7pH1GbfV}^MmkwW;PoY!G`u=Mu<^2 z7>rq)c4=kVHX$S`VONiRQ_OmQ6-|nZgJ}2!jG2N*?oJuT?E_AW8Bxk_wR!1oJqS|4 zFW2EDuU}%H@o(s_2OOmhQ-i9FW=APMgm&8=Dw3Hvz-}8+4jpq39cgkZ+8;3XI%56v z^|g`8!=Pc-LqoL826KwXZ_DJLgOulC3_g>WuD3GS9YGF0I{Hsd#O_d8u9dCNAlRf1 zNq3KbvN|?gb|APnzGw-pK6ND(5u}Wqg8nA+id}_RbUdaPUPwizUJm**bhvSyaR___ zP@_{L+N+Qf7mcR=)FanTLW;?EpL&pzJBuH6J|2HGD~1ENXlrqa$Ai^~-_@zV2Y)@1 zEbC!JEA!|qL)#t|j;><^(c^|VOtwmsO`H5=yMibtrMSE5_ZzR? zhx8g>feX-6sPpXY`o49nW1o*jQO1{lMYGs6;&&U?V(cs$hX3jUN=0HF9{v*#t~y&R z;iK>^5-GPK+MS_&a}>r?VPQ~aVXma}Y@t6CK?-<8dlUQyWs5csT_fhgXHO(o1&6{* zM(~Lg@AYyjpf2E}P~Yi*PvhyvgaQ0(>PvkB%N%TVq@XMvI`uNZ_LH!$0rofvn**>= zMZ#fC0k(;RodU2ZfdyZA5p*>{<`$@4iNwuHVt}j`Vc;&HLT6xD@*3KICHm*%Ki=^s z`tOA+3YJO`z<=j6Eu0YdK-{LCBt`sfG$BGw5}6iDiul{Jgt!1INz={~q7)aC3DF*0 znCwLGIstaAG28|G$4XoyA{_8l9nm9U6`{S1P7DH+X%W3d0sx#nM3CJ8^#f-U+!=8+ zfJQICox#h)T=?VyfrSD9l0|Uk?F6Ka1X31U7}Mbs3k>Huh`@$5IFl=|Ig5M=P&FLX il!y@WfBZMxJ5Fhu`EUSvIOhv)YK`?;{%xK|`2PcsaC$QU literal 10330 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png b/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png index 4b39a25ab1399bfa99098785e967d1bce267cb05..d46b6ded9b7b4cbe558dcf475ae18bbc7c50b096 100644 GIT binary patch literal 9032 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 Ju1IB({|EC_!h-++ literal 9223 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 diff --git a/third_party/test/golden_widget/flutter_logo.string.color_filter.png b/third_party/test/golden_widget/flutter_logo.string.color_filter.png index d80af0975390b8ab1d09108ebb7d44780e376578..0f02fbfe18a983b802848cc90e92329fd572b611 100644 GIT binary patch literal 7518 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 literal 7618 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 diff --git a/third_party/test/golden_widget/flutter_logo.string.ltr.png b/third_party/test/golden_widget/flutter_logo.string.ltr.png index e4402865634cfd5469cab823e5056404bd347fb8..7e70b9565dee51aef6a52f03b7b7119a82c15361 100644 GIT binary patch literal 3411 zcmeH{`CC(G7RTQNlnfY2SY)e)B!hs`qAgN^hTMrM2?!b^iZW~p2!bpM%9cuoLMJ3s zmQg?uQYcGNS`btE6n%nehfw#z6h$#e4NK69F@z9`s6FYwQQlwji~Cw0;`> zLzVK$W6i_pzU9-IG!U|KRvh@NJJ9~!^QNS-mOb7$g>#1YwftY>n`6FQyRbpN^o8g_ z;4=nV#8QW?z@3?bqF2_%FXeemW8d4wgw1K#e~{HLQvTC01AQ*~lenfB4r8U7L6 z7CRgsdjV-loW(x)S=3A||&Ek^r z=0cUo8u`*ObiHH|H97!jDz!%WZWwYD1E2u-7l0)b5G|rO5`aDcs{zbN05}4W0{F}X zN*9r7Kxmmc0V6`yfhvS+chcb$+ihLZHd-KZ%z-2uA;~@{ zlY$8l&mMr<1fZu)p#Zi4_|gQ1oeX$1-({)OO*vE>Rp~va?0fF#YsbD{xQyW)3nA?A zMG~bT_R7-p6!Gt0x6AL}Qv2y}JR-~_oV!m==ihedxzD(q`=Y##Q!{$qoFB{bahayel?6Jg(F16SS9HHM`%UCcpy+vZhf=QnY4{PgRem3ob4 z)b^LF>1mG^jQ_s2sOO05Efl%n12H0@ILdE9eL-oJ!5FK1VB>jSbnm(}h3R7$eJ<5V zzx~>FspAKKJ}RS*Q-&$c)%PKJmoJ43K9(ReklS;VJiFzlA&Hw-#;| z&Ac%WUa8bIwp2}_exmT*X#ZCU9UmCp-1uogH&jKt^NpA!3?hTU@fCzTy^7qxEiBN z*3tvP4MeGgBy5AFR7H4`Poz8<>;(%xlJ>aApS*K}vw45y2ghaGTt;LZ^?qpOTkWd= zQ0N2-t>+sFem$8pD)m3Rw8whfX^FF<>xWMs_Dv7did^=V4;0L%9S=DFEU%h?YiHu{ ziZ)+yMY2_^Kg)@bT?iZ3Z}lSMc})1~^~v=k8J{o`AM!FnwN)U{0R&>z zgk1+x4Fo6)*Un>CK0D8$(bSwzKW-?y!X?Bnt zA%jftT=9c7BWtq3OBppJzl3e3Gvmzuc_`YZrLTBMNLai`S mgdK&aD`&-l6$iip#uDYjYr3_J@>F}1AHg5*Vt2CQiv9o@we9f$ literal 3404 zcmeH|`&&|X9LK+hY%;A7Ej3qyNa}igGA~(E5#m7wGqu(-)6|-)P`fBzf@zY~25Lz% zua&deEZ1Y!R&!b|S47%W63Q%1%P2214ND``xzB0O{)+ki&q@lq9 z^G$3_5JK~LT+T*>=1>tLY$1LGq%<{aKU^@u#sD_D*tTR4Zj1zM-X7eyu+mVpJw$1M=DOs z_ZnF}I7;<8>8YsN!a0$BR!#SNO_H_y-wBEeG<)pF7r67}!6S+7-F$gTOLvi=t)c&v z%6Me#wa>Lbi+b|}G$>?t%{uUZcfhGO_Tlq8nhh>koHx6iTRYd(@vS3AZgC&`i zDp`PdA( z+54hSDZ;20eRIT7kntM_Uo=pFuox!*2LXJ9gCYP_0BZpl09b#AuyPjw+X0AhPzb;g zfHQzpx-V+VhAj~|fGi`tbR=7a5gH2>#z<&JMF})e^--2|iZN{CQFWuZ83I$F6Lz)l>{0dN4s0dN5DoCRCN zdK420F|r{>t_4O2-3~z$?OAAfAV`lJ5m|GkB&399&s*!T#x)jHv6ozjUz5yzCjU+<{zYOSrA-b}@EnUK@% zD@opARW+lX_oZEPe9g6Gy6^PJ$vEs13OwtqBlDfLS34YdJ}HKK!=^`D=fpTcXu9H# zrNWps2(^znz4Vvs5j6nE!IUzFB{{P#MFM0O5KhuDGw=(8R+_cucF@mOV!G_}I znp4rT0^SjD)&!glOgK*@gArncIn^Da#op6zsrRCgna3oxlclSjbXe$T5RqWWmYwOd z7dog9tjX`R5C%Z1^K|Hg%VpJZ+BTuW>k*q2Slsc zZT>dOlKRNs0L-g@XdxE=1Rh(Cw-c6AvX zgB5S|1NC8e30t9rRfQ4h$xoJoHRTiF(t1Yf4;j>lpjc}6Flwe(b=w$0*OgI*iHk)V z`f)4Qzs9PVJ!@uej%H5jYNirG$ZwE!G)R=ob+D1udwD+bjB4|VRZ5iH!pHtPmGwdX6Vt4K=k>JY_v$GN_jin8Adu87K(vC&TzzPvX)RVP=?4EY4rdXok1uxWI PNw^z4zhKTqc1+ek!J+%< diff --git a/third_party/test/golden_widget/flutter_logo.string.png b/third_party/test/golden_widget/flutter_logo.string.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..fc9ffa27529c1c7d62c7faecff5822448e6a262e 100644 GIT binary patch literal 10130 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 literal 10330 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.string.rtl.png b/third_party/test/golden_widget/flutter_logo.string.rtl.png index 6c8dd292777c2640514e08b937b8d3d764a80b9e..e65700f87fa6172382fd53a21970ffacf71e87d1 100644 GIT binary patch literal 3496 zcmeHJ>0gsq7QP8lf+K}Qlk#KBhR7fcrF2}{03ikvs6Zz2(@H8TP=taYxUdf?#F~I? zqcXJ!LBWx+EQ-SfRFFaCIvW2_Tx+FuV=^~N1I5M$)O?WZfEKG`!7^P5(NHS@%;xRLB0iy+|^$5?@N z1O1uxE9onVR8Zl->v`=@zewL4GE{MPfK(l0A;`^ctRPEM?_fxAUH?F9WDSDWHJM7bj0C>A~5l?;~>91QuI+I zfyj9X&ezKkt`d>(EoJ6(L}74|1p%CJ!O5~c2RZsk(UU+BWMTp)2>d``27*=)cy9ue ztz6{rH-zIzkx5_@HqgZ@dU{t2vU3{=r;($sf9xBv*V&)*WvIjH^7Ak zf+RVBW`~J6dVy)E;6#jR=o}PT40k9e5RnaufnuOOWnplKIWiqp<$%T=G+KMGxqxto zcY{qy<@_Q-Rma-Dd9;ZYRvhB^bzJ0;*FB!i9`RQ-iVW>Ve(m(m;|tH9&OB)Dn5}MN z_u1UFzdjZkapRU!;*9P%6kjfVw3tpr(82u`6ehK$O>Awl`6 zUEF;+`9-l=_Qo_OPg8HHIYvT7IAfup`^{fhwA@ZeA8cteN8*`F@c-dbZm7cVu zIcxI@!uIAa+r;7u%)yvpjNT=z1dti*n;`2N-mA5whA4%;Mgmyg%NB;NI0_ zh9)nc3Sb^+{lrv8Q#N*#0B`SL)utVM*BzK@O>@p6>9pEFeUh;R2NUBsEuZpyXL#wk zykh)e{_;!&DK(iIcR49)DUBpX8*L$zBecb5-L%H~h zIelO=s4@7s>_8SVK=-TPe`dD*ti4a56HotTsVVQ54FV@AvChm%!fMIqg+ zP=-}raJo~?<L#l~$=kMv`lQJky_(pQiRabJt)OzVq9Ou=tTIH^r{`vx+8V zA%ty7faI81av$1~Y0k;viKWtW4=$Poc&6%=o-6YydX+KS29%>5cku`n+rAt+pO-eH z_0!2Z%5Cef6gDKR^jr^YUTND~G6}iuV*vqTqtcw3O8L~;WcS#SHdk7knM$BNRTZ3W zS5xZQIMQr+yU)34xHX5B9xt!7gcbX_P%~ee{ zCMuFsSLeIfF@b65CXBaGG^J`!P~LuO7<@9?;QB7S-!hd+{kE6{1vB+N7P&KGFk@`| zImYWJ9{`-ImFHj6RZ*4N&hO&blv#x#^iAg&(^8Qga}i_hzdi?!KlT|O#vO1E{m)ib zU!A*;V&Us^?3FVO2{Wx44095DA_cv}VVCZ0C)am&w;T2zl53T;jCYTp4lZ*ck_kj2 zH|6CQsaH3BY&qvI{)fxbMDgJC2o;TBRVk}9L_WMd`6OdiUtLSNwT{yWbW~AnXoc!4 zKkyIff1w~Pj1Sq~0||1mAvPeoH$2o{(8wU5xk_e+MDW^?VJZbB0FW9`*~W=w4}_*J z(W;w@MqI5(ar%^P-9w7ryym5nkhe(a4h~4YD~?1YQ0%|?KVPDA2#40zS_RfB0DsQ> YSB+27^+L(4GaIXiuXg~ihI=^kzdytZE&u=k literal 3490 zcmeHH`CF4$7QP7xX{-$&AR?fUunPi?;#kWPGYPAe41-9l3brT=5*4vw5t6T%N}^&& z#9>XrO3``70+KO?5lCw(%!;JJYAn)z}hiFuVjVYO51eg??1$7ohXy{ zwye2xdWP{OzdSY&mFf|`UHNEq zP+It{{!>1Qi;)e>m~0B-I5QD7K#aJt0N@1R2tWt`Yyesb0Gv>F0pI|DApy{tD1-%o zApmRuij|1uvKAw^9(IDAATg@uePn_wOz9{w04Qw)1(I_4l%Oz}Xakd=fcvv1KrsRe z3n+RB-T+Q|!vM%40D=lmdT9Xs3_zNh9a`$S< zf+9ilodS`5Gk}ODkchfSA(gE$q@ec>EHu8AL~gweI|B|()aVH@4HOf!mjOFQpwa}-jHJ;do{fVxl|Rnr-UxM1me`iG|O?&&xa7|>Gqbg;Fr zZ(<}YM;Sk(i5BU;nH$Ki^4T-gx6P7wvo=5O)DUq21#m;^gDY{55VOrIc`YXmP z*_u|_ye%pA;IUZw(4QAwKk1%2V#6PkgTVRUE$J8*`1D-v|9YmRhs<30Q`QQuN$rAF zpgl)8G#htAG_3x4P_SOR-2%NQu8b|d9xO)Y5-7YSR#TDp=o4fONmGNw*Z;_Vey?NN zcMz3@8d8`$q`49kTl6gvbbT0O_yGq;=KDDI>i|0=VK+WI3XeUrob1c+t9m)ul(~W zaYP6kM|lx4Mr_V({A93LLctwGmMD&;k7*)?Q~x z-!G9lK_BiXnrzC9zW@BvFHBz9_fr_%cWD=rxK_6t>$^J}4^6xqMr6ZLLG;M@XZefz zX-QpEgZ5!wMe~Qg|9m&7LDg#s0}HeH2c8LZ;~HT`lI~J*+UrBE6*7Ns0YkPCZM6k2 z2ft`}+eK?p)oY*r+N6w`=V#DNwSPgCV{w}9Y>OQ*_K z)QY~YarQ$|=io?OrNvY=K`FwCsP|HH-e#6Z$%pQV!qSqXabX$gxF-mW{-d+=?JE%J zHX0d7+-C8WS5453d7*`Y+-MRc?<=n!=wFO+2%Ye$rdl0r#;H_(a|c=$-_;AS3Sfi5*+;^Rmw^2RO`*gzb;1nv}cjs zzkaa!b$;%PMuE{}4aS{cCcV2H)&GI*p5t$^Y5rkQ{pH4V zT@HsEe8@=(V9Rm=X^|834S(d(`xeV=H(U)s2FG6t4)gyo6!jO&WW zXYBa{YiGiQ-bWA7GUvN*4jk+@fakqe{vNmJHS(2K!p+8;}1L#rBU%tb2U>j}+Fx-mWp!?z+yAC`si x;c2P`T6$a&8V$e^LbqUZc`a99xdKpux^YoYx0dT9P&g9x2 1', () { + final PictureCache cache = PictureCache(); + expect(cache.maximumSize, equals(1000)); + + final MockPictureStreamCompleter completer1 = MockPictureStreamCompleter(); + final MockPictureStreamCompleter completer2 = MockPictureStreamCompleter(); + expect(completer1.cached, false); + expect(completer2.cached, false); + expect(cache.putIfAbsent(1, () => completer1), completer1); + expect(completer1.cached, true); + expect(completer2.cached, false); + + expect(cache.putIfAbsent(1, () => completer1), completer1); + expect(completer1.cached, true); + expect(completer2.cached, false); + + expect(cache.putIfAbsent(2, () => completer2), completer2); + expect(completer1.cached, true); + expect(completer2.cached, true); + + cache.maximumSize = 1; + + expect(completer1.cached, false); + expect(completer2.cached, true); + + cache.clear(); + expect(completer1.cached, false); + expect(completer2.cached, false); + }); + + test('Cache Tests with size = 1', () { final PictureCache cache = PictureCache(); expect(cache.maximumSize, equals(1000)); cache.maximumSize = 1; @@ -157,10 +187,22 @@ void main() { final MockPictureStreamCompleter completer1 = MockPictureStreamCompleter(); final MockPictureStreamCompleter completer2 = MockPictureStreamCompleter(); + expect(completer1.cached, false); + expect(completer2.cached, false); expect(cache.putIfAbsent(1, () => completer1), completer1); + expect(completer1.cached, true); + expect(completer2.cached, false); + expect(cache.putIfAbsent(1, () => completer1), completer1); + expect(completer1.cached, true); + expect(completer2.cached, false); + expect(cache.putIfAbsent(2, () => completer2), completer2); + expect(completer1.cached, false); + expect(completer2.cached, true); cache.clear(); + expect(completer1.cached, false); + expect(completer2.cached, false); }); } diff --git a/third_party/test/picture_stream_test.dart b/third_party/test/picture_stream_test.dart index 6f10c681d812..d96291561bb6 100644 --- a/third_party/test/picture_stream_test.dart +++ b/third_party/test/picture_stream_test.dart @@ -1,5 +1,6 @@ import 'dart:ui'; +import 'package:flutter/rendering.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:test/test.dart'; @@ -9,19 +10,101 @@ void main() { final Canvas canvas = Canvas(recorder); canvas.drawPaint(Paint()..color = const Color(0xFFFA0000)); final Picture picture = recorder.endRecording(); - + final LayerHandle layer = LayerHandle(); + layer.layer = PictureLayer(Rect.zero)..picture = picture; final PictureInfo info1 = PictureInfo( - picture: picture, + layerHandle: layer, viewport: Rect.zero, size: Size.zero, ); final PictureInfo info2 = PictureInfo( - picture: picture, + layerHandle: layer, viewport: Rect.zero, size: Size.zero, ); expect(info1.hashCode, equals(info2.hashCode)); expect(info1, equals(info2)); }); + + test('Completer disposes layer when removed from cache and no listeners', + () async { + final LayerHandle layer = LayerHandle(); + layer.layer = PictureLayer(Rect.zero); + final PictureInfo info = PictureInfo( + layerHandle: layer, + viewport: Rect.zero, + size: Size.zero, + ); + + final OneFramePictureStreamCompleter completer = + OneFramePictureStreamCompleter(Future.value(info)); + + await null; // wait an event turn for future to resolve. + + expect(layer.layer, isNotNull); + expect(completer.cached, false); + + completer.cached = true; + expect(layer.layer, isNotNull); + completer.cached = false; + expect(layer.layer, null); + }); + + test( + 'Completer disposes layer when removed from cache and no listeners after having a listener', + () async { + final LayerHandle layer = LayerHandle(); + layer.layer = PictureLayer(Rect.zero); + final PictureInfo info = PictureInfo( + layerHandle: layer, + viewport: Rect.zero, + size: Size.zero, + ); + + final OneFramePictureStreamCompleter completer = + OneFramePictureStreamCompleter(Future.value(info)); + + await null; // wait an event turn for future to resolve. + + expect(layer.layer, isNotNull); + expect(completer.cached, false); + + void _listener(PictureInfo? image, bool syncCall) {} + completer.addListener(_listener); + completer.cached = true; + + completer.removeListener(_listener); + expect(layer.layer, isNotNull); + completer.cached = false; + expect(layer.layer, isNull); + }); + + test('Completer disposes layer when last listener drops and not in cache', + () async { + final LayerHandle layer = LayerHandle(); + layer.layer = PictureLayer(Rect.zero); + final PictureInfo info = PictureInfo( + layerHandle: layer, + viewport: Rect.zero, + size: Size.zero, + ); + + final OneFramePictureStreamCompleter completer = + OneFramePictureStreamCompleter(Future.value(info)); + + await null; // wait an event turn for future to resolve. + + expect(layer.layer, isNotNull); + expect(completer.cached, false); + + void _listener(PictureInfo? image, bool syncCall) {} + completer.addListener(_listener); + completer.cached = true; + + completer.cached = false; + expect(layer.layer, isNotNull); + completer.removeListener(_listener); + expect(layer.layer, isNull); + }); } diff --git a/third_party/test/vector_drawable_test.dart b/third_party/test/vector_drawable_test.dart index 32f62b916966..1468de983527 100644 --- a/third_party/test/vector_drawable_test.dart +++ b/third_party/test/vector_drawable_test.dart @@ -48,4 +48,20 @@ void main() { ]; expect(data.buffer.asUint8List(), expected); }); + + test('SvgPictureDecoder sets isComplexHint', () async { + final PictureInfo info = await svg.svgPictureStringDecoder( + ''' + + + +''', + false, + null, + 'test', + theme: const SvgTheme(), + ); + + expect(info.layerHandle.layer!.isComplexHint, true); + }); } diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index df94eb65f930..a258efa550fd 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -7,7 +7,6 @@ import 'dart:ui' show window; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_svg/src/unbounded_color_filtered.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -42,7 +41,7 @@ void main() { ); await tester.pumpAndSettle(); expect(PictureProvider.cache.count, 1); - expect(find.byType(UnboundedColorFiltered), findsNothing); + expect(find.byType(ColorFiltered), findsNothing); }); testWidgets('SvgPicture does not invalidate the cache when color changes', From 700a145a441fa9e32c497bd78a6949ce64a1643f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 13 Oct 2021 00:36:34 -0700 Subject: [PATCH 408/512] Fix layer reuse, add regression test (#608) * Fix layer reuse, add regression test * Make golden a little more tolerant --- third_party/lib/avd.dart | 12 +- third_party/lib/src/picture_stream.dart | 65 ++++++---- third_party/lib/src/render_picture.dart | 14 ++- third_party/lib/svg.dart | 12 +- .../test/golden_widget/columns_and_rows.png | Bin 6193 -> 23184 bytes .../test/golden_widget/text_color_filter.png | Bin 2322 -> 2316 bytes .../test/golden_widget/two_of_same.png | Bin 0 -> 2010 bytes third_party/test/picture_stream_test.dart | 62 ++++------ third_party/test/vector_drawable_test.dart | 4 +- third_party/test/widget_svg_test.dart | 112 ++++++++++++++---- 10 files changed, 167 insertions(+), 114 deletions(-) create mode 100644 third_party/test/golden_widget/two_of_same.png diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index a38a0f277ae6..85864a61bc8c 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -35,12 +35,8 @@ class Avd { final Picture pic = avdRoot.toPicture( clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter); - final LayerHandle handle = LayerHandle(); - handle.layer = PictureLayer(avdRoot.viewport.viewBoxRect) - ..picture = pic - ..isComplexHint = true; return PictureInfo( - layerHandle: handle, + picture: pic, viewport: avdRoot.viewport.viewBoxRect, ); } @@ -58,12 +54,8 @@ class Avd { clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter, ); - final LayerHandle handle = LayerHandle(); - handle.layer = PictureLayer(avdRoot.viewport.viewBoxRect) - ..picture = pic - ..isComplexHint = true; return PictureInfo( - layerHandle: handle, + picture: pic, viewport: avdRoot.viewport.viewBoxRect, size: avdRoot.viewport.size, ); diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart index 09769adc1c94..e7e1cafdb9db 100644 --- a/third_party/lib/src/picture_stream.dart +++ b/third_party/lib/src/picture_stream.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:ui' show Picture, Rect, hashValues, Size; +import 'dart:ui' show Picture, Rect, Size; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; @@ -22,26 +22,25 @@ class _PictureListenerPair { } /// Represents information about a ui.Picture to be drawn on a canvas. -@immutable class PictureInfo { /// Creates a new PictureInfo object. - const PictureInfo({ - required this.layerHandle, + PictureInfo({ + required Picture picture, required this.viewport, this.size = Size.infinite, - }) : assert(layerHandle != null), // ignore: unnecessary_null_comparison + }) : assert(picture != null), // ignore: unnecessary_null_comparison assert(viewport != null), // ignore: unnecessary_null_comparison - assert(size != null); // ignore: unnecessary_null_comparison - - /// The [PictureLayer] that holds the [picture]. - final LayerHandle layerHandle; + assert(size != null), // ignore: unnecessary_null_comparison + _picture = picture; /// The raw picture. /// /// This picture's lifecycle will be managed by the provider. It will be /// reused as long as the picture does not change, and disposed when the - /// provider loses all of its listeners or it is unset. - Picture get picture => layerHandle.layer!.picture!; + /// provider loses all of its listeners or it is unset. Once it has been + /// disposed, it will return null. + Picture? get picture => _picture; + Picture? _picture; /// The viewport enclosing the coordinates used in the picture. final Rect viewport; @@ -50,18 +49,18 @@ class PictureInfo { /// [viewport.size]. final Size size; - @override - int get hashCode => hashValues(layerHandle, viewport, size); + /// Creates a [PictureLayer] that will suitably manage the lifecycle of the + /// [picture]. + PictureLayer createLayer() { + return _NonOwningPictureLayer(viewport) + ..picture = picture + ..isComplexHint = true; + } - @override - bool operator ==(Object other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is PictureInfo && - other.layerHandle == layerHandle && - other.viewport == viewport && - other.size == size; + void _dispose() { + assert(_picture != null); + _picture!.dispose(); + _picture = null; } } @@ -210,7 +209,7 @@ abstract class PictureStreamCompleter with Diagnosticable { return; } if (!value && _listeners.isEmpty) { - _current?.layerHandle.layer = null; + _current?._dispose(); _current = null; } _cached = value; @@ -248,7 +247,7 @@ abstract class PictureStreamCompleter with Diagnosticable { (_PictureListenerPair pair) => pair.listener == listener, ); if (_listeners.isEmpty && !cached) { - _current?.layerHandle.layer = null; + _current?._dispose(); _current = null; } } @@ -256,7 +255,7 @@ abstract class PictureStreamCompleter with Diagnosticable { /// Calls all the registered listeners to notify them of a new picture. @protected void setPicture(PictureInfo? picture) { - _current?.layerHandle.layer = null; + _current?._dispose(); _current = picture; if (_listeners.isEmpty) { return; @@ -339,3 +338,19 @@ class OneFramePictureStreamCompleter extends PictureStreamCompleter { }); } } + +class _NonOwningPictureLayer extends PictureLayer { + _NonOwningPictureLayer(Rect canvasBounds) : super(canvasBounds); + + @override + Picture? get picture => _picture; + + Picture? _picture; + + @override + set picture(Picture? picture) { + markNeedsAddToScene(); + // Do not dispose the picture, it's owned by the stream/cache. + _picture = picture; + } +} diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index 4ce5cf083355..b37fdcfcfb62 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -126,10 +126,11 @@ class RenderPicture extends RenderBox { return; } _picture = val; + _pictureHandle.layer = _picture?.createLayer(); assert(() { - if (_picture != null && _picture!.layerHandle.layer != null) { - assert(_picture!.layerHandle.layer!.isComplexHint == true); - assert(_picture!.layerHandle.layer!.willChangeHint == false); + if (_pictureHandle.layer != null) { + assert(_pictureHandle.layer!.isComplexHint); + assert(!_pictureHandle.layer!.willChangeHint); } return true; }()); @@ -171,8 +172,11 @@ class RenderPicture extends RenderBox { final LayerHandle _clipHandle = LayerHandle(); + final LayerHandle _pictureHandle = LayerHandle(); + void _addPicture(PaintingContext context, Offset offset) { assert(picture != null); + assert(_pictureHandle.layer != null); if (allowDrawingOutsideViewBox != true) { final Rect viewportRect = Offset.zero & _picture!.viewport.size; _clipHandle.layer = context.pushClipRect( @@ -180,13 +184,13 @@ class RenderPicture extends RenderBox { offset, viewportRect, (PaintingContext context, Offset offset) { - context.addLayer(picture!.layerHandle.layer!); + context.addLayer(_pictureHandle.layer!); }, oldLayer: _clipHandle.layer, ); } else { _clipHandle.layer = null; - context.addLayer(picture!.layerHandle.layer!); + context.addLayer(_pictureHandle.layer!); } } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 514d63073e8f..4f9ec2aa2a71 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -56,12 +56,8 @@ class Svg { clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, colorFilter: colorFilter, ); - final LayerHandle handle = LayerHandle(); - handle.layer = PictureLayer(svgRoot.viewport.viewBoxRect) - ..picture = pic - ..isComplexHint = true; return PictureInfo( - layerHandle: handle, + picture: pic, viewport: svgRoot.viewport.viewBoxRect, size: svgRoot.viewport.size, ); @@ -90,12 +86,8 @@ class Svg { colorFilter: colorFilter, size: svgRoot.viewport.viewBox, ); - final LayerHandle handle = LayerHandle(); - handle.layer = PictureLayer(svgRoot.viewport.viewBoxRect) - ..picture = pic - ..isComplexHint = true; return PictureInfo( - layerHandle: handle, + picture: pic, viewport: svgRoot.viewport.viewBoxRect, size: svgRoot.viewport.size, ); diff --git a/third_party/test/golden_widget/columns_and_rows.png b/third_party/test/golden_widget/columns_and_rows.png index b97f0f8049ec67aedf1c1939d20f438687bdf1a4..34053145e281c2d6bf83eb6acc305fd547a1555f 100644 GIT binary patch literal 23184 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 OB;)Do=d#Wzp$Pykcd0!9 literal 2322 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI zLpXq-h9jkefq`R>r;B4q#hkZy4*EI;inw0n-Y8pjADM;h*fhT5Ge5tQW%%&s+iG^8ht@kc07*$kCI*HS z77hl634#g?3=VFig1`V71*0J_8UmvsF!Vye{B0ONLxcMV)6aXWnE(Ht^D|;Ei1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI zLpXq-h9jkefq}in)5S5QV$R#^hFlB^JS>i1|JPr;b;!#`F#VK+(=A+Fc y#K3TbLx6!n!L4D?_+iu`qaiRF0?-iH&a?a?lgM5T7GQnMz~JfX=d#Wzp$PyJc`eoe literal 0 HcmV?d00001 diff --git a/third_party/test/picture_stream_test.dart b/third_party/test/picture_stream_test.dart index d96291561bb6..51ca1919015a 100644 --- a/third_party/test/picture_stream_test.dart +++ b/third_party/test/picture_stream_test.dart @@ -1,38 +1,18 @@ import 'dart:ui'; -import 'package:flutter/rendering.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:test/test.dart'; void main() { - test('PictureInfo Tests', () { + test('Completer disposes layer when removed from cache and no listeners', + () async { final PictureRecorder recorder = PictureRecorder(); final Canvas canvas = Canvas(recorder); canvas.drawPaint(Paint()..color = const Color(0xFFFA0000)); final Picture picture = recorder.endRecording(); - final LayerHandle layer = LayerHandle(); - layer.layer = PictureLayer(Rect.zero)..picture = picture; - final PictureInfo info1 = PictureInfo( - layerHandle: layer, - viewport: Rect.zero, - size: Size.zero, - ); - final PictureInfo info2 = PictureInfo( - layerHandle: layer, - viewport: Rect.zero, - size: Size.zero, - ); - expect(info1.hashCode, equals(info2.hashCode)); - expect(info1, equals(info2)); - }); - - test('Completer disposes layer when removed from cache and no listeners', - () async { - final LayerHandle layer = LayerHandle(); - layer.layer = PictureLayer(Rect.zero); final PictureInfo info = PictureInfo( - layerHandle: layer, + picture: picture, viewport: Rect.zero, size: Size.zero, ); @@ -42,22 +22,25 @@ void main() { await null; // wait an event turn for future to resolve. - expect(layer.layer, isNotNull); + expect(info.picture, isNotNull); expect(completer.cached, false); completer.cached = true; - expect(layer.layer, isNotNull); + expect(info.picture, isNotNull); completer.cached = false; - expect(layer.layer, null); + expect(info.picture, null); }); test( 'Completer disposes layer when removed from cache and no listeners after having a listener', () async { - final LayerHandle layer = LayerHandle(); - layer.layer = PictureLayer(Rect.zero); + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + canvas.drawPaint(Paint()..color = const Color(0xFFFA0000)); + final Picture picture = recorder.endRecording(); + final PictureInfo info = PictureInfo( - layerHandle: layer, + picture: picture, viewport: Rect.zero, size: Size.zero, ); @@ -67,7 +50,7 @@ void main() { await null; // wait an event turn for future to resolve. - expect(layer.layer, isNotNull); + expect(info.picture, isNotNull); expect(completer.cached, false); void _listener(PictureInfo? image, bool syncCall) {} @@ -75,17 +58,20 @@ void main() { completer.cached = true; completer.removeListener(_listener); - expect(layer.layer, isNotNull); + expect(info.picture, isNotNull); completer.cached = false; - expect(layer.layer, isNull); + expect(info.picture, isNull); }); test('Completer disposes layer when last listener drops and not in cache', () async { - final LayerHandle layer = LayerHandle(); - layer.layer = PictureLayer(Rect.zero); + final PictureRecorder recorder = PictureRecorder(); + final Canvas canvas = Canvas(recorder); + canvas.drawPaint(Paint()..color = const Color(0xFFFA0000)); + final Picture picture = recorder.endRecording(); + final PictureInfo info = PictureInfo( - layerHandle: layer, + picture: picture, viewport: Rect.zero, size: Size.zero, ); @@ -95,7 +81,7 @@ void main() { await null; // wait an event turn for future to resolve. - expect(layer.layer, isNotNull); + expect(info.picture, isNotNull); expect(completer.cached, false); void _listener(PictureInfo? image, bool syncCall) {} @@ -103,8 +89,8 @@ void main() { completer.cached = true; completer.cached = false; - expect(layer.layer, isNotNull); + expect(info.picture, isNotNull); completer.removeListener(_listener); - expect(layer.layer, isNull); + expect(info.picture, isNull); }); } diff --git a/third_party/test/vector_drawable_test.dart b/third_party/test/vector_drawable_test.dart index 1468de983527..4adfcc05d313 100644 --- a/third_party/test/vector_drawable_test.dart +++ b/third_party/test/vector_drawable_test.dart @@ -37,7 +37,7 @@ void main() { 'test', theme: const SvgTheme(), ); - final Image image = await info.picture.toImage(2, 2); + final Image image = await info.picture!.toImage(2, 2); final ByteData data = (await image.toByteData())!; const List expected = [ @@ -62,6 +62,6 @@ void main() { theme: const SvgTheme(), ); - expect(info.layerHandle.layer!.isComplexHint, true); + expect(info.createLayer().isComplexHint, true); }); } diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index a258efa550fd..198d7931f469 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -10,6 +10,30 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_test/flutter_test.dart'; +class _TolerantComparator extends LocalFileComparator { + _TolerantComparator(Uri testFile) : super(testFile); + + @override + Future compare(Uint8List imageBytes, Uri golden) async { + final ComparisonResult result = await GoldenFileComparator.compareLists( + imageBytes, + await getGoldenBytes(golden), + ); + if (!result.passed) { + final String error = await generateFailureOutput(result, golden, basedir); + if (result.diffPercent >= .06) { + throw FlutterError(error); + } else { + print( + 'Warning - golden differed less than .06% (${result.diffPercent}%), ' + 'ignoring failure but producing output'); + print(error); + } + } + return true; + } +} + Future _checkWidgetAndGolden(Key key, String filename) async { final Finder widgetFinder = find.byKey(key); expect(widgetFinder, findsOneWidget); @@ -20,6 +44,16 @@ void main() { late FakeHttpClientResponse fakeResponse; late FakeHttpClientRequest fakeRequest; late FakeHttpClient fakeHttpClient; + + setUpAll(() { + final LocalFileComparator oldComparator = + goldenFileComparator as LocalFileComparator; + final _TolerantComparator newComparator = _TolerantComparator( + Uri.parse(oldComparator.basedir.toString() + 'test')); + expect(oldComparator.basedir, newComparator.basedir); + goldenFileComparator = newComparator; + }); + setUp(() { PictureProvider.cache.clear(); svg.cacheColorFilterOverride = null; @@ -558,7 +592,7 @@ void main() { await tester.pumpAndSettle(); await _checkWidgetAndGolden(key, 'text_color_filter.png'); - }, skip: !isLinux); + }); testWidgets('Nested SVG elements report a FlutterError', (WidgetTester tester) async { @@ -717,6 +751,27 @@ void main() { await tester.pumpAndSettle(); expect(renderObject.clipBehavior, equals(Clip.antiAlias)); }); + + testWidgets('SvgPicture - two of the same', (WidgetTester tester) async { + // Regression test to make sure the same SVG can render twice in the same + // view. If layers are incorrectly reused, this will fail. + await tester.pumpWidget(RepaintBoundary( + child: Directionality( + textDirection: TextDirection.ltr, + child: Row( + children: [ + SvgPicture.string(simpleSvg), + SvgPicture.string(simpleSvg), + ], + ), + ))); + await tester.pumpAndSettle(); + + await expectLater( + find.byType(RepaintBoundary), + matchesGoldenFile('golden_widget/two_of_same.png'), + ); + }); } class FakeAssetBundle extends Fake implements AssetBundle { @@ -788,29 +843,37 @@ class FakeHttpClientResponse extends Fake implements HttpClientResponse { } } -const String svgStr = - ''' - - - - - - - - - - - - - - - - - - -'''; +const String simpleSvg = ''' + + + +'''; + +const String svgStr = ''' + + + + + + + + + + + + + + + + + + + + +'''; -const String stickFigureSvgStr = ''' +const String stickFigureSvgStr = ''' + svg/stick_figure @@ -827,6 +890,7 @@ const String stickFigureSvgStr = ''' -'''; + +'''; final Uint8List svgBytes = utf8.encode(svgStr) as Uint8List; From e4ecef6bfc79ed83967c996d8557a937f4a48641 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 15 Oct 2021 21:11:31 -0700 Subject: [PATCH 409/512] Make new painting method opt in to allow migration --- third_party/lib/src/render_picture.dart | 70 ++++++++++++++++++- .../lib/src/unbounded_color_filtered.dart | 54 ++++++++++++++ third_party/lib/svg.dart | 29 ++++++-- 3 files changed, 148 insertions(+), 5 deletions(-) create mode 100644 third_party/lib/src/unbounded_color_filtered.dart diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index b37fdcfcfb62..c12d3903db4c 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -14,8 +14,17 @@ class RawPicture extends LeafRenderObjectWidget { Key? key, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, + this.useLegacyPaint = true, }) : super(key: key); + /// Whether to use a less efficient, but completely visually compatible, + /// method of painting the picture. + /// + /// This flag is intended to assist clients with migration to the layer based + /// painting method. Once all known clients have been migrated, it will be + /// deprecated and become a no-op. + final bool useLegacyPaint; + /// The picture to paint. final PictureInfo? picture; @@ -34,11 +43,13 @@ class RawPicture extends LeafRenderObjectWidget { matchTextDirection: matchTextDirection, textDirection: matchTextDirection ? Directionality.of(context) : null, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, + useLegacyPaint: useLegacyPaint, ); } @override void updateRenderObject(BuildContext context, RenderPicture renderObject) { + assert(renderObject.useLegacyPaint == useLegacyPaint); renderObject ..picture = picture ..matchTextDirection = matchTextDirection @@ -64,12 +75,21 @@ class RenderPicture extends RenderBox { bool matchTextDirection = false, TextDirection? textDirection, bool? allowDrawingOutsideViewBox, + this.useLegacyPaint = true, }) : _matchTextDirection = matchTextDirection, _textDirection = textDirection, _allowDrawingOutsideViewBox = allowDrawingOutsideViewBox { this.picture = picture; } + /// Whether to use a less efficient, but completely visually compatible, + /// method of painting the picture. + /// + /// This flag is intended to assist clients with migration to the layer based + /// painting method. Once all known clients have been migrated, it will be + /// deprecated and become a no-op. + final bool useLegacyPaint; + /// Optional color to use to draw a thin rectangle around the canvas. /// /// Only applied if asserts are enabled (e.g. debug mode). @@ -165,7 +185,7 @@ class RenderPicture extends RenderBox { } @override - bool get isRepaintBoundary => true; + bool get isRepaintBoundary => !useLegacyPaint; final LayerHandle _transformHandle = LayerHandle(); @@ -197,11 +217,59 @@ class RenderPicture extends RenderBox { @override void dispose() { _transformHandle.layer = null; + _pictureHandle.layer = null; + _clipHandle.layer = null; super.dispose(); } + void _legacyPaintif(PaintingContext context, Offset offset) { + if (picture == null || picture!.picture == null || size == Size.zero) { + return; + } + context.canvas.save(); + context.canvas.translate(offset.dx, offset.dy); + if (_flipHorizontally) { + context.canvas.translate(size.width, 0.0); + context.canvas.scale(-1.0, 1.0); + } + + // this is sometimes useful for debugging, e.g. to draw + // a thin red border around the drawing. + assert(() { + if (RenderPicture.debugRectColor != null && + RenderPicture.debugRectColor!.alpha > 0) { + context.canvas.drawRect( + Offset.zero & size, + Paint() + ..color = debugRectColor! + ..style = PaintingStyle.stroke); + } + return true; + }()); + final Matrix4 transform = Matrix4.identity(); + if (scaleCanvasToViewBox( + transform, + size, + _picture!.viewport, + _picture!.size, + )) { + context.canvas.transform(transform.storage); + } + final Rect viewportRect = Offset.zero & _picture!.viewport.size; + if (allowDrawingOutsideViewBox != true) { + context.canvas.clipRect(viewportRect); + } + context.canvas.drawPicture(picture!.picture!); + context.canvas.restore(); + } + @override void paint(PaintingContext context, Offset offset) { + if (useLegacyPaint) { + _legacyPaintif(context, offset); + return; + } + if (picture == null || size == Size.zero) { return; } diff --git a/third_party/lib/src/unbounded_color_filtered.dart b/third_party/lib/src/unbounded_color_filtered.dart new file mode 100644 index 000000000000..1787897ff4a7 --- /dev/null +++ b/third_party/lib/src/unbounded_color_filtered.dart @@ -0,0 +1,54 @@ +import 'package:flutter/rendering.dart'; +import 'package:flutter/widgets.dart'; + +/// Supports SvgPicture - not meant for public use, visible for testing. +@visibleForTesting +class UnboundedColorFiltered extends SingleChildRenderObjectWidget { + /// Supports SvgPicture - not meant for public use, visible for testing. + const UnboundedColorFiltered({ + Key? key, + required this.colorFilter, + required Widget child, + }) : super(key: key, child: child); + + /// The color filter to apply. + final ColorFilter? colorFilter; + + @override + _UnboundedColorFilteredRenderBox createRenderObject(BuildContext context) => + _UnboundedColorFilteredRenderBox(colorFilter); + + @override + void updateRenderObject( + BuildContext context, + covariant _UnboundedColorFilteredRenderBox renderObject, + ) { + renderObject.colorFilter = colorFilter; + } +} + +class _UnboundedColorFilteredRenderBox extends RenderProxyBox { + _UnboundedColorFilteredRenderBox( + this._colorFilter, + ); + + ColorFilter? _colorFilter; + ColorFilter? get colorFilter => _colorFilter; + set colorFilter(ColorFilter? value) { + if (value == _colorFilter) { + return; + } + _colorFilter = value; + markNeedsPaint(); + } + + @override + void paint(PaintingContext context, Offset offset) { + final Paint paint = Paint()..colorFilter = colorFilter; + context.canvas.saveLayer(offset & size, paint); + if (child != null) { + context.paintChild(child!, offset); + } + context.canvas.restore(); + } +} diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 4f9ec2aa2a71..98cabccd3392 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -14,6 +14,7 @@ import 'src/picture_provider.dart'; import 'src/picture_stream.dart'; import 'src/render_picture.dart'; import 'src/svg/theme.dart'; +import 'src/unbounded_color_filtered.dart'; import 'src/vector_drawable.dart'; /// Instance for [Svg]'s utility methods, which can produce a [DrawableRoot] @@ -236,6 +237,7 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, + this.useLegacyPaint = true, }) : super(key: key); /// Instantiates a widget that renders an SVG picture from an [AssetBundle]. @@ -337,6 +339,7 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, + this.useLegacyPaint = true, }) : pictureProvider = ExactAssetPicture( allowDrawingOutsideViewBox == true ? svgStringDecoderOutsideViewBoxBuilder @@ -401,6 +404,7 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, + this.useLegacyPaint = true, }) : pictureProvider = NetworkPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBoxBuilder @@ -461,6 +465,7 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, + this.useLegacyPaint = true, }) : pictureProvider = FilePicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBoxBuilder @@ -517,6 +522,7 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, + this.useLegacyPaint = true, }) : pictureProvider = MemoryPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBoxBuilder @@ -573,6 +579,7 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, + this.useLegacyPaint = true, }) : pictureProvider = StringPicture( allowDrawingOutsideViewBox == true ? svgStringDecoderOutsideViewBoxBuilder @@ -585,6 +592,14 @@ class SvgPicture extends StatefulWidget { colorFilter = _getColorFilter(color, colorBlendMode), super(key: key); + /// Whether to use a less efficient, but completely visually compatible, + /// method of painting the picture. + /// + /// This flag is intended to assist clients with migration to the layer based + /// painting method. Once all known clients have been migrated, it will be + /// deprecated and become a no-op. + final bool useLegacyPaint; + /// The default placeholder for a SVG that may take time to parse or /// retrieve, e.g. from a network location. static WidgetBuilder defaultPlaceholderBuilder = @@ -853,6 +868,7 @@ class _SvgPictureState extends State { _picture, matchTextDirection: widget.matchTextDirection, allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, + useLegacyPaint: widget.useLegacyPaint, ), ), ), @@ -860,10 +876,15 @@ class _SvgPictureState extends State { if (widget.pictureProvider.colorFilter == null && widget.colorFilter != null) { - child = ColorFiltered( - colorFilter: widget.colorFilter!, - child: child, - ); + child = widget.useLegacyPaint + ? UnboundedColorFiltered( + colorFilter: widget.colorFilter, + child: child, + ) + : ColorFiltered( + colorFilter: widget.colorFilter!, + child: child, + ); } } else { child = widget.placeholderBuilder == null From 7c646a2a5a23920121afa007d0bead68c0fa8660 Mon Sep 17 00:00:00 2001 From: Sarbagya Dhaubanjar Date: Thu, 28 Oct 2021 22:41:42 +0545 Subject: [PATCH 410/512] Conditionally import `File` from `dart:io` (#613) * added conditional `File` * replaced usage of `dart:io` with conditional file --- third_party/lib/src/picture_provider.dart | 2 +- third_party/lib/src/utilities/_file_io.dart | 1 + third_party/lib/src/utilities/_file_none.dart | 13 +++++++++++++ third_party/lib/src/utilities/file.dart | 1 + third_party/lib/svg.dart | 4 ++-- 5 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 third_party/lib/src/utilities/_file_io.dart create mode 100644 third_party/lib/src/utilities/_file_none.dart create mode 100644 third_party/lib/src/utilities/file.dart diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 503d6c3f2080..13e650fe9294 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -3,7 +3,6 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:io'; import 'dart:typed_data'; import 'dart:ui' show BlendMode, Color, ColorFilter, Locale, Rect, TextDirection, hashValues; @@ -15,6 +14,7 @@ import 'package:flutter/widgets.dart' import 'picture_cache.dart'; import 'picture_stream.dart'; +import 'utilities/file.dart'; import 'utilities/http.dart'; /// The signature of a function that can decode raw SVG data into a [Picture]. diff --git a/third_party/lib/src/utilities/_file_io.dart b/third_party/lib/src/utilities/_file_io.dart new file mode 100644 index 000000000000..3da0f6adbf79 --- /dev/null +++ b/third_party/lib/src/utilities/_file_io.dart @@ -0,0 +1 @@ +export 'dart:io' show File; diff --git a/third_party/lib/src/utilities/_file_none.dart b/third_party/lib/src/utilities/_file_none.dart new file mode 100644 index 000000000000..595e0f8db421 --- /dev/null +++ b/third_party/lib/src/utilities/_file_none.dart @@ -0,0 +1,13 @@ +import 'dart:typed_data'; + +/// Fake File for Web +abstract class File { + /// Get the path of the file. + String get path; + + /// Reads the entire file contents as a list of bytes. + /// + /// Returns a `Future` that completes with the list of bytes that + /// is the contents of the file. + Future readAsBytes(); +} diff --git a/third_party/lib/src/utilities/file.dart b/third_party/lib/src/utilities/file.dart new file mode 100644 index 000000000000..e469e274b0e9 --- /dev/null +++ b/third_party/lib/src/utilities/file.dart @@ -0,0 +1 @@ +export '_file_io.dart' if (dart.library.html) '_file_none.dart'; diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 98cabccd3392..f8b179fad5e5 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -1,20 +1,20 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:io' show File; import 'dart:typed_data'; import 'dart:ui' show Picture; import 'package:flutter/foundation.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/widgets.dart'; -import 'package:flutter_svg/src/svg/default_theme.dart'; import 'parser.dart'; import 'src/picture_provider.dart'; import 'src/picture_stream.dart'; import 'src/render_picture.dart'; +import 'src/svg/default_theme.dart'; import 'src/svg/theme.dart'; import 'src/unbounded_color_filtered.dart'; +import 'src/utilities/file.dart'; import 'src/vector_drawable.dart'; /// Instance for [Svg]'s utility methods, which can produce a [DrawableRoot] From 8dffeb7130e1d0f8ce941ac8d83bc638c62e100b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 3 Nov 2021 17:03:55 -0700 Subject: [PATCH 411/512] Remove difficult to use flag --- third_party/lib/src/render_picture.dart | 70 +------------------ .../lib/src/unbounded_color_filtered.dart | 54 -------------- third_party/lib/svg.dart | 29 ++------ 3 files changed, 5 insertions(+), 148 deletions(-) delete mode 100644 third_party/lib/src/unbounded_color_filtered.dart diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart index c12d3903db4c..b37fdcfcfb62 100644 --- a/third_party/lib/src/render_picture.dart +++ b/third_party/lib/src/render_picture.dart @@ -14,17 +14,8 @@ class RawPicture extends LeafRenderObjectWidget { Key? key, this.matchTextDirection = false, this.allowDrawingOutsideViewBox = false, - this.useLegacyPaint = true, }) : super(key: key); - /// Whether to use a less efficient, but completely visually compatible, - /// method of painting the picture. - /// - /// This flag is intended to assist clients with migration to the layer based - /// painting method. Once all known clients have been migrated, it will be - /// deprecated and become a no-op. - final bool useLegacyPaint; - /// The picture to paint. final PictureInfo? picture; @@ -43,13 +34,11 @@ class RawPicture extends LeafRenderObjectWidget { matchTextDirection: matchTextDirection, textDirection: matchTextDirection ? Directionality.of(context) : null, allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, - useLegacyPaint: useLegacyPaint, ); } @override void updateRenderObject(BuildContext context, RenderPicture renderObject) { - assert(renderObject.useLegacyPaint == useLegacyPaint); renderObject ..picture = picture ..matchTextDirection = matchTextDirection @@ -75,21 +64,12 @@ class RenderPicture extends RenderBox { bool matchTextDirection = false, TextDirection? textDirection, bool? allowDrawingOutsideViewBox, - this.useLegacyPaint = true, }) : _matchTextDirection = matchTextDirection, _textDirection = textDirection, _allowDrawingOutsideViewBox = allowDrawingOutsideViewBox { this.picture = picture; } - /// Whether to use a less efficient, but completely visually compatible, - /// method of painting the picture. - /// - /// This flag is intended to assist clients with migration to the layer based - /// painting method. Once all known clients have been migrated, it will be - /// deprecated and become a no-op. - final bool useLegacyPaint; - /// Optional color to use to draw a thin rectangle around the canvas. /// /// Only applied if asserts are enabled (e.g. debug mode). @@ -185,7 +165,7 @@ class RenderPicture extends RenderBox { } @override - bool get isRepaintBoundary => !useLegacyPaint; + bool get isRepaintBoundary => true; final LayerHandle _transformHandle = LayerHandle(); @@ -217,59 +197,11 @@ class RenderPicture extends RenderBox { @override void dispose() { _transformHandle.layer = null; - _pictureHandle.layer = null; - _clipHandle.layer = null; super.dispose(); } - void _legacyPaintif(PaintingContext context, Offset offset) { - if (picture == null || picture!.picture == null || size == Size.zero) { - return; - } - context.canvas.save(); - context.canvas.translate(offset.dx, offset.dy); - if (_flipHorizontally) { - context.canvas.translate(size.width, 0.0); - context.canvas.scale(-1.0, 1.0); - } - - // this is sometimes useful for debugging, e.g. to draw - // a thin red border around the drawing. - assert(() { - if (RenderPicture.debugRectColor != null && - RenderPicture.debugRectColor!.alpha > 0) { - context.canvas.drawRect( - Offset.zero & size, - Paint() - ..color = debugRectColor! - ..style = PaintingStyle.stroke); - } - return true; - }()); - final Matrix4 transform = Matrix4.identity(); - if (scaleCanvasToViewBox( - transform, - size, - _picture!.viewport, - _picture!.size, - )) { - context.canvas.transform(transform.storage); - } - final Rect viewportRect = Offset.zero & _picture!.viewport.size; - if (allowDrawingOutsideViewBox != true) { - context.canvas.clipRect(viewportRect); - } - context.canvas.drawPicture(picture!.picture!); - context.canvas.restore(); - } - @override void paint(PaintingContext context, Offset offset) { - if (useLegacyPaint) { - _legacyPaintif(context, offset); - return; - } - if (picture == null || size == Size.zero) { return; } diff --git a/third_party/lib/src/unbounded_color_filtered.dart b/third_party/lib/src/unbounded_color_filtered.dart deleted file mode 100644 index 1787897ff4a7..000000000000 --- a/third_party/lib/src/unbounded_color_filtered.dart +++ /dev/null @@ -1,54 +0,0 @@ -import 'package:flutter/rendering.dart'; -import 'package:flutter/widgets.dart'; - -/// Supports SvgPicture - not meant for public use, visible for testing. -@visibleForTesting -class UnboundedColorFiltered extends SingleChildRenderObjectWidget { - /// Supports SvgPicture - not meant for public use, visible for testing. - const UnboundedColorFiltered({ - Key? key, - required this.colorFilter, - required Widget child, - }) : super(key: key, child: child); - - /// The color filter to apply. - final ColorFilter? colorFilter; - - @override - _UnboundedColorFilteredRenderBox createRenderObject(BuildContext context) => - _UnboundedColorFilteredRenderBox(colorFilter); - - @override - void updateRenderObject( - BuildContext context, - covariant _UnboundedColorFilteredRenderBox renderObject, - ) { - renderObject.colorFilter = colorFilter; - } -} - -class _UnboundedColorFilteredRenderBox extends RenderProxyBox { - _UnboundedColorFilteredRenderBox( - this._colorFilter, - ); - - ColorFilter? _colorFilter; - ColorFilter? get colorFilter => _colorFilter; - set colorFilter(ColorFilter? value) { - if (value == _colorFilter) { - return; - } - _colorFilter = value; - markNeedsPaint(); - } - - @override - void paint(PaintingContext context, Offset offset) { - final Paint paint = Paint()..colorFilter = colorFilter; - context.canvas.saveLayer(offset & size, paint); - if (child != null) { - context.paintChild(child!, offset); - } - context.canvas.restore(); - } -} diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index f8b179fad5e5..ec1d11a9938a 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -13,7 +13,6 @@ import 'src/picture_stream.dart'; import 'src/render_picture.dart'; import 'src/svg/default_theme.dart'; import 'src/svg/theme.dart'; -import 'src/unbounded_color_filtered.dart'; import 'src/utilities/file.dart'; import 'src/vector_drawable.dart'; @@ -237,7 +236,6 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, - this.useLegacyPaint = true, }) : super(key: key); /// Instantiates a widget that renders an SVG picture from an [AssetBundle]. @@ -339,7 +337,6 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, - this.useLegacyPaint = true, }) : pictureProvider = ExactAssetPicture( allowDrawingOutsideViewBox == true ? svgStringDecoderOutsideViewBoxBuilder @@ -404,7 +401,6 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, - this.useLegacyPaint = true, }) : pictureProvider = NetworkPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBoxBuilder @@ -465,7 +461,6 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, - this.useLegacyPaint = true, }) : pictureProvider = FilePicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBoxBuilder @@ -522,7 +517,6 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, - this.useLegacyPaint = true, }) : pictureProvider = MemoryPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBoxBuilder @@ -579,7 +573,6 @@ class SvgPicture extends StatefulWidget { this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, this.currentColor, - this.useLegacyPaint = true, }) : pictureProvider = StringPicture( allowDrawingOutsideViewBox == true ? svgStringDecoderOutsideViewBoxBuilder @@ -592,14 +585,6 @@ class SvgPicture extends StatefulWidget { colorFilter = _getColorFilter(color, colorBlendMode), super(key: key); - /// Whether to use a less efficient, but completely visually compatible, - /// method of painting the picture. - /// - /// This flag is intended to assist clients with migration to the layer based - /// painting method. Once all known clients have been migrated, it will be - /// deprecated and become a no-op. - final bool useLegacyPaint; - /// The default placeholder for a SVG that may take time to parse or /// retrieve, e.g. from a network location. static WidgetBuilder defaultPlaceholderBuilder = @@ -868,7 +853,6 @@ class _SvgPictureState extends State { _picture, matchTextDirection: widget.matchTextDirection, allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, - useLegacyPaint: widget.useLegacyPaint, ), ), ), @@ -876,15 +860,10 @@ class _SvgPictureState extends State { if (widget.pictureProvider.colorFilter == null && widget.colorFilter != null) { - child = widget.useLegacyPaint - ? UnboundedColorFiltered( - colorFilter: widget.colorFilter, - child: child, - ) - : ColorFiltered( - colorFilter: widget.colorFilter!, - child: child, - ); + child = ColorFiltered( + colorFilter: widget.colorFilter!, + child: child, + ); } } else { child = widget.placeholderBuilder == null From 1e63469e3e184dd239d63810f79bbe19b0999c85 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 3 Nov 2021 17:04:56 -0700 Subject: [PATCH 412/512] version bumps --- third_party/CHANGELOG.md | 7 +++++++ third_party/pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 0137c0ab2c73..75dcdadd9b2b 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGES +## 1.0.0 + +- New widget/RenderObject implementation to avoid rebuilds/paints when + near or overlapping an animating widget. Also should improve raster + cacheability. +- Correctly list web as a supported platform. + ## 0.23.0+1 - Missing commit that reduced breakages introduced in 0.23.0 diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index fdb963fa78e5..465f037a8783 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 0.23.0+1 +version: 1.0.0 dependencies: flutter: From 7520174eaf7a4afcb6010aeaa7ba282f97b83988 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 7 Nov 2021 20:39:44 -0800 Subject: [PATCH 413/512] Fix issues with hashing mutable objects --- third_party/lib/src/picture_cache.dart | 5 + third_party/lib/src/picture_provider.dart | 378 ++++++++++---------- third_party/lib/src/svg/theme.dart | 3 + third_party/test/picture_provider_test.dart | 15 + 4 files changed, 211 insertions(+), 190 deletions(-) diff --git a/third_party/lib/src/picture_cache.dart b/third_party/lib/src/picture_cache.dart index 239cf9a49445..93c6cda322ea 100644 --- a/third_party/lib/src/picture_cache.dart +++ b/third_party/lib/src/picture_cache.dart @@ -50,6 +50,11 @@ class PictureCache { _cache.clear(); } + /// Evicts a single entry from the cache, returning true if successful. + bool evict(Object key) { + return _cache.remove(key) != null; + } + /// Returns the previously cached [PictureStream] for the given key, if available; /// if not, calls the given callback to obtain it first. In either case, the /// key is moved to the "most recently used" position. diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 13e650fe9294..8e9424ed9f42 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -14,6 +14,7 @@ import 'package:flutter/widgets.dart' import 'picture_cache.dart'; import 'picture_stream.dart'; +import 'svg/theme.dart'; import 'utilities/file.dart'; import 'utilities/http.dart'; @@ -302,10 +303,18 @@ class PictureConfiguration { /// } /// ``` @optionalTypeArgs -abstract class PictureProvider { +abstract class PictureProvider { /// Abstract const constructor. This constructor enables subclasses to provide /// const constructors so that they can be used in const expressions. - PictureProvider(this.colorFilter); + PictureProvider(this.colorFilter, {required this.decoderBuilder}) + : decoder = decoderBuilder(null); + + /// The decoder builder to build a [decoder] when [currentColor] changes. + final PictureInfoDecoderBuilder decoderBuilder; + + /// The [PictureInfoDecoder] to use for loading this picture. + @visibleForTesting + PictureInfoDecoder decoder; /// The [PictureCache] for [Picture] objects created by [PictureProvider] /// implementations. @@ -328,7 +337,19 @@ abstract class PictureProvider { Color? _currentColor; /// Sets the [_currentColor] to [color]. - set currentColor(Color? color); + set currentColor(Color? color) { + if (_currentColor == color) { + return; + } + decoder = decoderBuilder(color); + _currentColor = color; + if (_lastKey != null) { + cache.evict(_lastKey!); + _lastKey = null; + } + } + + T? _lastKey; /// Resolves this Picture provider using the given `configuration`, returning /// an [PictureStream]. @@ -342,10 +363,9 @@ abstract class PictureProvider { // ignore: unnecessary_null_comparison assert(picture != null); final PictureStream stream = PictureStream(); - T? obtainedKey; obtainKey(picture).then( (T key) { - obtainedKey = key; + _lastKey = key; stream.setCompleter( cache.putIfAbsent( key!, @@ -367,7 +387,7 @@ abstract class PictureProvider { informationCollector: () sync* { yield DiagnosticsProperty( 'Picture provider', this); - yield DiagnosticsProperty('Picture key', obtainedKey, + yield DiagnosticsProperty('Picture key', _lastKey, defaultValue: null); })); }); @@ -394,18 +414,65 @@ abstract class PictureProvider { String toString() => '$runtimeType()'; } +/// An immutable key representing the current state of a [PictureProvider]. +@immutable +class PictureKey { + /// Creates a new immutable key reprenseting the current state of a + /// [PictureProvider] for the [PictureCache]. + const PictureKey( + this.keyData, { + required this.colorFilter, + required this.theme, + }); + + /// Some unique identifier for the source of this picture, e.g. a file name or + /// URL. + /// + /// If this is an iterable, it is assumed that the iterable will not be + /// modified after creating this object. + final T keyData; + + /// The color filter applied when this key was created. + final ColorFilter? colorFilter; + + /// The theme used when this key was created. + final SvgTheme theme; + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + return other is PictureKey && + keyData == other.keyData && + colorFilter == other.colorFilter && + theme == other.theme; + } + + @override + int get hashCode => hashValues(keyData.hashCode, colorFilter, theme); + + @override + String toString() => + 'PictureKey($keyData, colorFilter: $colorFilter, theme: $theme)'; +} + /// Key for the picture obtained by an [AssetPicture] or [ExactAssetPicture]. /// /// This is used to identify the precise resource in the [pictureCache]. @immutable -class AssetBundlePictureKey { +class AssetBundlePictureKey extends PictureKey { /// Creates the key for an [AssetPicture] or [AssetBundlePictureProvider]. /// /// The arguments must not be null. - const AssetBundlePictureKey( - {required this.bundle, required this.name, this.colorFilter}) - : assert(bundle != null), // ignore: unnecessary_null_comparison - assert(name != null); // ignore: unnecessary_null_comparison + const AssetBundlePictureKey({ + required this.bundle, + required String name, + ColorFilter? colorFilter, + required SvgTheme theme, + }) : assert(bundle != null), // ignore: unnecessary_null_comparison + assert(name != null), // ignore: unnecessary_null_comparison + super(name, colorFilter: colorFilter, theme: theme); /// The bundle from which the picture will be obtained. /// @@ -415,10 +482,7 @@ class AssetBundlePictureKey { /// The key to use to obtain the resource from the [bundle]. This is the /// argument passed to [AssetBundle.load]. - final String name; - - /// The [ColorFilter], if any, to be applied to the drawing. - final ColorFilter? colorFilter; + String get name => keyData; @override bool operator ==(dynamic other) { @@ -428,15 +492,16 @@ class AssetBundlePictureKey { return other is AssetBundlePictureKey && bundle == other.bundle && name == other.name && - colorFilter == other.colorFilter; + colorFilter == other.colorFilter && + theme == other.theme; } @override - int get hashCode => hashValues(bundle, name, colorFilter); + int get hashCode => hashValues(bundle, name, colorFilter, theme); @override String toString() => - '$runtimeType(bundle: $bundle, name: "$name", colorFilter: $colorFilter)'; + '$runtimeType(bundle: $bundle, name: "$name", colorFilter: $colorFilter, theme: $theme)'; } /// A subclass of [PictureProvider] that knows about [AssetBundle]s. @@ -444,26 +509,13 @@ class AssetBundlePictureKey { /// This factors out the common logic of [AssetBundle]-based [PictureProvider] /// classes, simplifying what subclasses must implement to just [obtainKey]. abstract class AssetBundlePictureProvider - extends PictureProvider { + extends PictureProvider { /// Abstract const constructor. This constructor enables subclasses to provide /// const constructors so that they can be used in const expressions. - AssetBundlePictureProvider(this.decoderBuilder, ColorFilter? colorFilter) + AssetBundlePictureProvider(PictureInfoDecoderBuilder decoderBuilder, + ColorFilter? colorFilter) : assert(decoderBuilder != null), // ignore: unnecessary_null_comparison - decoder = decoderBuilder(null), - super(colorFilter); - - /// The decoder builder to build a [decoder] when [currentColor] changes. - final PictureInfoDecoderBuilder decoderBuilder; - - /// The decoder to use to turn a string into a [PictureInfo] object. - @visibleForTesting - PictureInfoDecoder decoder; - - @override - set currentColor(Color? color) { - _currentColor = color; - decoder = decoderBuilder(_currentColor); - } + super(colorFilter, decoderBuilder: decoderBuilder); /// Converts a key into an [PictureStreamCompleter], and begins fetching the /// picture using [_loadAsync]. @@ -499,6 +551,32 @@ abstract class AssetBundlePictureProvider } } +/// The [PictureKey.keyData] for a [NetworkPicture]. +@immutable +class NetworkPictureKeyData { + /// Creates [PictureKey.keyData] for a [NetworkPicture]. + const NetworkPictureKeyData({required this.url, required this.headers}); + + /// The URL to request. + final String url; + + /// The headers include in the GET request to [url]. + final Map? headers; + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + return other is NetworkPictureKeyData && + other.url == url && + other.headers == headers; + } + + @override + int get hashCode => hashValues(url, headers); +} + /// Fetches the given URL from the network, associating it with the given scale. /// /// The picture will be cached regardless of cache headers from the server. @@ -509,22 +587,15 @@ abstract class AssetBundlePictureProvider // TODO(ianh): Find some way to honour cache headers to the extent that when the // last reference to a picture is released, we proactively evict the picture from // our cache if the headers describe the picture as having expired at that point. -class NetworkPicture extends PictureProvider { +class NetworkPicture + extends PictureProvider, Uint8List> { /// Creates an object that fetches the picture at the given URL. /// /// The arguments must not be null. - NetworkPicture(this.decoderBuilder, this.url, + NetworkPicture(PictureInfoDecoderBuilder decoderBuilder, this.url, {this.headers, ColorFilter? colorFilter}) : assert(url != null), // ignore: unnecessary_null_comparison - decoder = decoderBuilder(null), - super(colorFilter); - - /// The decoder builder to build a [decoder] when [currentColor] changes. - final PictureInfoDecoderBuilder decoderBuilder; - - /// The decoder to use to turn a [Uint8List] into a [PictureInfo] object. - @visibleForTesting - PictureInfoDecoder decoder; + super(colorFilter, decoderBuilder: decoderBuilder); /// The URL from which the picture will be fetched. final String url; @@ -533,29 +604,36 @@ class NetworkPicture extends PictureProvider { final Map? headers; @override - set currentColor(Color? color) { - _currentColor = color; - decoder = decoderBuilder(_currentColor); - } - - @override - Future obtainKey(PictureConfiguration picture) { - return SynchronousFuture(this); + Future> obtainKey( + PictureConfiguration picture) { + return SynchronousFuture>( + PictureKey( + NetworkPictureKeyData(url: url, headers: headers), + colorFilter: colorFilter, + theme: SvgTheme( + currentColor: currentColor, + ), + ), + ); } @override - PictureStreamCompleter load(NetworkPicture key, + PictureStreamCompleter load(PictureKey key, {PictureErrorListener? onError}) { return OneFramePictureStreamCompleter(_loadAsync(key, onError: onError), informationCollector: () sync* { yield DiagnosticsProperty('Picture provider', this); - yield DiagnosticsProperty('Picture key', key); + yield DiagnosticsProperty>( + 'Picture key', + key, + ); }); } - Future _loadAsync(NetworkPicture key, + Future _loadAsync(PictureKey key, {PictureErrorListener? onError}) async { - assert(key == this); + assert(url == key.keyData.url); + assert(headers == key.keyData.headers); final Uint8List bytes = await httpGet(url, headers: headers); if (onError != null) { @@ -571,19 +649,6 @@ class NetworkPicture extends PictureProvider { return decoder(bytes, colorFilter, key.toString()); } - @override - bool operator ==(dynamic other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is NetworkPicture && - url == other.url && - colorFilter == other.colorFilter; - } - - @override - int get hashCode => hashValues(url.hashCode, colorFilter); - @override String toString() => '$runtimeType("$url", headers: $headers, colorFilter: $colorFilter)'; @@ -595,39 +660,34 @@ class NetworkPicture extends PictureProvider { /// See also: /// /// * [SvgPicture.file] for a shorthand of an [SvgPicture] widget backed by [FilePicture]. -class FilePicture extends PictureProvider { +class FilePicture extends PictureProvider, Uint8List> { /// Creates an object that decodes a [File] as a picture. /// /// The arguments must not be null. - FilePicture(this.decoderBuilder, this.file, {ColorFilter? colorFilter}) + FilePicture(PictureInfoDecoderBuilder decoderBuilder, this.file, + {ColorFilter? colorFilter}) : assert(decoderBuilder != null), // ignore: unnecessary_null_comparison assert(file != null), // ignore: unnecessary_null_comparison - decoder = decoderBuilder(null), - super(colorFilter); + super(colorFilter, decoderBuilder: decoderBuilder); /// The file to decode into a picture. final File file; - /// The decoder builder to build a [decoder] when [currentColor] changes. - final PictureInfoDecoderBuilder decoderBuilder; - - /// The [PictureInfoDecoder] to use for loading this picture. - @visibleForTesting - PictureInfoDecoder decoder; - - @override - set currentColor(Color? color) { - _currentColor = color; - decoder = decoderBuilder(_currentColor); - } - @override - Future obtainKey(PictureConfiguration picture) { - return SynchronousFuture(this); + Future> obtainKey(PictureConfiguration picture) { + return SynchronousFuture>( + PictureKey( + file.path, + colorFilter: colorFilter, + theme: SvgTheme( + currentColor: currentColor, + ), + ), + ); } @override - PictureStreamCompleter load(FilePicture key, + PictureStreamCompleter load(PictureKey key, {PictureErrorListener? onError}) { return OneFramePictureStreamCompleter(_loadAsync(key, onError: onError), informationCollector: () sync* { @@ -635,9 +695,9 @@ class FilePicture extends PictureProvider { }); } - Future _loadAsync(FilePicture key, + Future _loadAsync(PictureKey key, {PictureErrorListener? onError}) async { - assert(key == this); + assert(key.keyData == file.path); final Uint8List data = await file.readAsBytes(); if (data.isEmpty) { @@ -656,19 +716,6 @@ class FilePicture extends PictureProvider { return decoder(data, colorFilter, key.toString()); } - @override - bool operator ==(dynamic other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is FilePicture && - file.path == other.file.path && - other.colorFilter == colorFilter; - } - - @override - int get hashCode => hashValues(file.path.hashCode, colorFilter); - @override String toString() => '$runtimeType("${file.path}", colorFilter: $colorFilter)'; @@ -686,45 +733,40 @@ class FilePicture extends PictureProvider { /// See also: /// /// * [SvgPicture.memory] for a shorthand of an [SvgPicture] widget backed by [MemoryPicture]. -class MemoryPicture extends PictureProvider { +class MemoryPicture extends PictureProvider, Uint8List> { /// Creates an object that decodes a [Uint8List] buffer as a picture. /// /// The arguments must not be null. - MemoryPicture(this.decoderBuilder, this.bytes, {ColorFilter? colorFilter}) + MemoryPicture(PictureInfoDecoderBuilder decoderBuilder, this.bytes, + {ColorFilter? colorFilter}) : assert(bytes != null), // ignore: unnecessary_null_comparison - decoder = decoderBuilder(null), - super(colorFilter); - - /// The decoder builder to build a [decoder] when [currentColor] changes. - final PictureInfoDecoderBuilder decoderBuilder; - - /// The [PictureInfoDecoder] to use when drawing this picture. - @visibleForTesting - PictureInfoDecoder decoder; + super(colorFilter, decoderBuilder: decoderBuilder); /// The bytes to decode into a picture. final Uint8List bytes; @override - set currentColor(Color? color) { - _currentColor = color; - decoder = decoderBuilder(_currentColor); - } - - @override - Future obtainKey(PictureConfiguration picture) { - return SynchronousFuture(this); + Future> obtainKey(PictureConfiguration picture) { + return SynchronousFuture>( + PictureKey( + bytes, + colorFilter: colorFilter, + theme: SvgTheme( + currentColor: currentColor, + ), + ), + ); } @override - PictureStreamCompleter load(MemoryPicture key, + PictureStreamCompleter load(PictureKey key, {PictureErrorListener? onError}) { return OneFramePictureStreamCompleter(_loadAsync(key, onError: onError)); } - Future _loadAsync(MemoryPicture key, + Future _loadAsync(PictureKey key, {PictureErrorListener? onError}) async { - assert(key == this); + assert(key.keyData == bytes); if (onError != null) { return decoder( bytes, @@ -738,19 +780,6 @@ class MemoryPicture extends PictureProvider { return decoder(bytes, colorFilter, key.toString()); } - @override - bool operator ==(dynamic other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is MemoryPicture && - bytes == other.bytes && - colorFilter == other.colorFilter; - } - - @override - int get hashCode => hashValues(bytes.hashCode, colorFilter); - @override String toString() => '$runtimeType(${describeIdentity(bytes)})'; } @@ -767,47 +796,42 @@ class MemoryPicture extends PictureProvider { /// See also: /// /// * [SvgPicture.string] for a shorthand of an [SvgPicture] widget backed by [StringPicture]. -class StringPicture extends PictureProvider { +class StringPicture extends PictureProvider, String> { /// Creates an object that decodes a [Uint8List] buffer as a picture. /// /// The arguments must not be null. - StringPicture(this.decoderBuilder, this.string, {ColorFilter? colorFilter}) + StringPicture(PictureInfoDecoderBuilder decoderBuilder, this.string, + {ColorFilter? colorFilter}) : assert(string != null), // ignore: unnecessary_null_comparison - decoder = decoderBuilder(null), - super(colorFilter); - - /// The decoder builder to build a [decoder] when [currentColor] changes. - final PictureInfoDecoderBuilder decoderBuilder; - - /// The [PictureInfoDecoder] to use for decoding this picture. - @visibleForTesting - PictureInfoDecoder decoder; + super(colorFilter, decoderBuilder: decoderBuilder); /// The string to decode into a picture. final String string; @override - set currentColor(Color? color) { - _currentColor = color; - decoder = decoderBuilder(_currentColor); - } - - @override - Future obtainKey(PictureConfiguration picture) { - return SynchronousFuture(this); + Future> obtainKey(PictureConfiguration picture) { + return SynchronousFuture>( + PictureKey( + string, + colorFilter: colorFilter, + theme: SvgTheme( + currentColor: currentColor, + ), + ), + ); } @override - PictureStreamCompleter load(StringPicture key, + PictureStreamCompleter load(PictureKey key, {PictureErrorListener? onError}) { return OneFramePictureStreamCompleter(_loadAsync(key, onError: onError)); } Future _loadAsync( - StringPicture key, { + PictureKey key, { PictureErrorListener? onError, }) { - assert(key == this); + assert(key.keyData == string); if (onError != null) { return decoder( string, @@ -821,19 +845,6 @@ class StringPicture extends PictureProvider { return decoder(string, colorFilter, key.toString()); } - @override - bool operator ==(dynamic other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is StringPicture && - string == other.string && - colorFilter == other.colorFilter; - } - - @override - int get hashCode => hashValues(string.hashCode, colorFilter); - @override String toString() => '$runtimeType(${describeIdentity(string)}, colorFilter: $colorFilter)'; @@ -958,24 +969,11 @@ class ExactAssetPicture extends AssetBundlePictureProvider { bundle: bundle ?? picture.bundle ?? rootBundle, name: keyName, colorFilter: colorFilter, + theme: SvgTheme(currentColor: currentColor), ), ); } - @override - bool operator ==(dynamic other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is ExactAssetPicture && - keyName == other.keyName && - bundle == other.bundle && - colorFilter == other.colorFilter; - } - - @override - int get hashCode => hashValues(keyName, bundle, colorFilter); - @override String toString() => '$runtimeType(name: "$keyName", bundle: $bundle, colorFilter: $colorFilter)'; diff --git a/third_party/lib/src/svg/theme.dart b/third_party/lib/src/svg/theme.dart index ed2060055b98..49eb71e637b4 100644 --- a/third_party/lib/src/svg/theme.dart +++ b/third_party/lib/src/svg/theme.dart @@ -1,6 +1,9 @@ import 'dart:ui'; +import 'package:meta/meta.dart'; + /// A theme used when decoding an SVG picture. +@immutable class SvgTheme { /// Instantiates an SVG theme with the [currentColor]. const SvgTheme({ diff --git a/third_party/test/picture_provider_test.dart b/third_party/test/picture_provider_test.dart index 01e4a5c8ce8a..baedd2f46d6a 100644 --- a/third_party/test/picture_provider_test.dart +++ b/third_party/test/picture_provider_test.dart @@ -142,5 +142,20 @@ void main() { equals(color), ); }); + + test('Evicts from cache when currentColor changes', () async { + expect(PictureProvider.cache.count, 0); + const Color color = Color(0xFFB0E3BE); + final StringPicture stringPicture = StringPicture(decoderBuilder, ''); + + final PictureStream stream = + stringPicture.resolve(createLocalPictureConfiguration(null)); + + await null; + expect(PictureProvider.cache.count, 1); + + stringPicture.currentColor = color; + expect(PictureProvider.cache.count, 0); + }); }); } From f76c1d8d2f0a2e3fb5e25b665c3c613123e3718f Mon Sep 17 00:00:00 2001 From: Bartosz Selwesiuk Date: Thu, 18 Nov 2021 21:37:40 +0100 Subject: [PATCH 414/512] Add support for em units (#605) * feat: add parseDoubleWithUnits to calculate em values * feat: add fontSize to SvgTheme * feat: add fontSize to SvgPicture and PictureProvider * feat: use parseDoubleWithUnits with SVG elements that support em/ex * fix: PictureProvider should rebuild if currentColor is null * test: fix tests after introducing fontSize * test: add DefaultSvgTheme fontSize tests * fix: update SvgTheme hashCode to include fontSize * refactor: replace currentColor and fontSize SvgPicture properties with SvgTheme * test: fix parseDashOffset tests * test: add parseStyle fontSize tests (stroke width, dash array, dash offset) * test: update parseStyle test names * test: add missing DefaultSvgTheme tests * fix: do not print a warning when using em units on the root svg width/height * test: add SvgParser fontSize tests (svg, use, text, radialGradient, linearGradient, image) * test: add SvgPicture fontSize tests for shapes (circle, rect, ellipse, line) * test: PictureProvider rebuilds a decoder when fontSize changes * test: use SvgTheme.empty in tests * test: add relative font size tests * build: update path_drawing to ^0.5.1+1 * feat: use default SvgTheme * fix: typo * refactor: make PictureInfoDecoderBuilder receive an SvgTheme rather than a list of properties * test: fix PictureProvider tests that use SvgTheme * fix: initialize default decoder when PictureProvider is created * feat: PictureProvider loadAsync should return non-nullable PictureInfo * feat: fallback to default SvgTheme if null theme is set * feat: make PictureProvider theme non nullable --- third_party/lib/parser.dart | 2 +- third_party/lib/src/picture_provider.dart | 49 ++- third_party/lib/src/svg/parser_state.dart | 202 ++++++++--- third_party/lib/src/svg/parsers.dart | 14 +- third_party/lib/src/svg/theme.dart | 16 +- third_party/lib/src/svg/xml_parsers.dart | 68 +++- third_party/lib/src/utilities/numbers.dart | 51 ++- third_party/lib/svg.dart | 101 +++--- third_party/pubspec.yaml | 2 +- third_party/test/default_theme_test.dart | 100 +++++- third_party/test/error_test.dart | 5 +- third_party/test/golden_widget/circle.em.png | Bin 0 -> 10223 bytes third_party/test/golden_widget/ellipse.em.png | Bin 0 -> 6672 bytes third_party/test/golden_widget/line.em.png | Bin 0 -> 6500 bytes third_party/test/golden_widget/rect.em.png | Bin 0 -> 4071 bytes third_party/test/picture_cache_test.dart | 27 +- third_party/test/picture_provider_test.dart | 315 +++++++++++------- third_party/test/svg_parsers_test.dart | 284 ++++++++++++++-- third_party/test/theme_test.dart | 30 +- third_party/test/vector_drawable_test.dart | 2 - third_party/test/widget_svg_test.dart | 102 +++++- third_party/test/xml_svg_test.dart | 161 ++++++++- third_party/tool/gen_golden.dart | 7 +- 23 files changed, 1194 insertions(+), 344 deletions(-) create mode 100644 third_party/test/golden_widget/circle.em.png create mode 100644 third_party/test/golden_widget/ellipse.em.png create mode 100644 third_party/test/golden_widget/line.em.png create mode 100644 third_party/test/golden_widget/rect.em.png diff --git a/third_party/lib/parser.dart b/third_party/lib/parser.dart index d720192f79f5..ee2e4eb262c9 100644 --- a/third_party/lib/parser.dart +++ b/third_party/lib/parser.dart @@ -18,7 +18,7 @@ class SvgParser { /// Defaults to false. Future parse( String str, { - SvgTheme? theme, + SvgTheme theme = const SvgTheme(), String? key, bool warningsAsErrors = false, }) async { diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 8e9424ed9f42..e39511916ee2 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -29,9 +29,9 @@ typedef PictureInfoDecoder = Future Function( ); /// The signature of a builder that returns a [PictureInfoDecoder] -/// based on the [currentColor]. +/// based on the provided [theme]. typedef PictureInfoDecoderBuilder = PictureInfoDecoder Function( - Color? currentColor, + SvgTheme theme, ); /// Creates an [PictureConfiguration] based on the given [BuildContext] (and @@ -307,9 +307,10 @@ abstract class PictureProvider { /// Abstract const constructor. This constructor enables subclasses to provide /// const constructors so that they can be used in const expressions. PictureProvider(this.colorFilter, {required this.decoderBuilder}) - : decoder = decoderBuilder(null); + : _theme = const SvgTheme(), + decoder = decoderBuilder(const SvgTheme()); - /// The decoder builder to build a [decoder] when [currentColor] changes. + /// The decoder builder to build a [decoder] when [theme] changes. final PictureInfoDecoderBuilder decoderBuilder; /// The [PictureInfoDecoder] to use for loading this picture. @@ -331,18 +332,23 @@ abstract class PictureProvider { /// The color filter to apply to the picture, if any. final ColorFilter? colorFilter; - /// The default color applied to SVG elements that inherit the color property. + /// The default theme used when parsing SVG elements. @visibleForTesting - Color? get currentColor => _currentColor; - Color? _currentColor; + SvgTheme get theme => _theme; + SvgTheme _theme; - /// Sets the [_currentColor] to [color]. - set currentColor(Color? color) { - if (_currentColor == color) { + /// Sets the [_theme] to [theme]. + /// + /// A theme is used when parsing SVG elements. Changing the theme + /// rebuilds a [decoder] using [decoderBuilder] and the new theme. + /// This will make the decoded SVG picture use properties from + /// the new theme. + set theme(SvgTheme theme) { + if (_theme == theme) { return; } - decoder = decoderBuilder(color); - _currentColor = color; + decoder = decoderBuilder(theme); + _theme = theme; if (_lastKey != null) { cache.evict(_lastKey!); _lastKey = null; @@ -537,6 +543,7 @@ abstract class AssetBundlePictureProvider Future _loadAsync( AssetBundlePictureKey key, PictureErrorListener? onError) async { final String data = await key.bundle.loadString(key.name); + if (onError != null) { return decoder( data, @@ -610,9 +617,7 @@ class NetworkPicture PictureKey( NetworkPictureKeyData(url: url, headers: headers), colorFilter: colorFilter, - theme: SvgTheme( - currentColor: currentColor, - ), + theme: theme, ), ); } @@ -679,9 +684,7 @@ class FilePicture extends PictureProvider, Uint8List> { PictureKey( file.path, colorFilter: colorFilter, - theme: SvgTheme( - currentColor: currentColor, - ), + theme: theme, ), ); } @@ -751,9 +754,7 @@ class MemoryPicture extends PictureProvider, Uint8List> { PictureKey( bytes, colorFilter: colorFilter, - theme: SvgTheme( - currentColor: currentColor, - ), + theme: theme, ), ); } @@ -814,9 +815,7 @@ class StringPicture extends PictureProvider, String> { PictureKey( string, colorFilter: colorFilter, - theme: SvgTheme( - currentColor: currentColor, - ), + theme: theme, ), ); } @@ -969,7 +968,7 @@ class ExactAssetPicture extends AssetBundlePictureProvider { bundle: bundle ?? picture.bundle ?? rootBundle, name: keyName, colorFilter: colorFilter, - theme: SvgTheme(currentColor: currentColor), + theme: theme, ), ); } diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index a2514352dff4..c1952765933e 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -19,7 +19,8 @@ final Set _unhandledElements = {'title', 'desc'}; typedef _ParseFunc = Future? Function( SvgParserState parserState, bool warningsAsErrors); -typedef _PathFunc = Path? Function(Map attributes); +typedef _PathFunc = Path? Function( + Map attributes, double fontSize); final RegExp _trimPattern = RegExp(r'[\r|\n|\t]'); @@ -50,15 +51,22 @@ const Map _svgPathFuncs = { Offset _parseCurrentOffset(SvgParserState parserState, Offset? lastOffset) { final String? x = parserState.attribute('x', def: null); final String? y = parserState.attribute('y', def: null); + final double fontSize = parserState.fontSize; return Offset( x != null - ? parseDouble(x)! - : parseDouble(parserState.attribute('dx', def: '0'))! + + ? parseDoubleWithUnits(x, fontSize: fontSize)! + : parseDoubleWithUnits( + parserState.attribute('dx', def: '0'), + fontSize: fontSize, + )! + (lastOffset?.dx ?? 0), y != null - ? parseDouble(y)! - : parseDouble(parserState.attribute('dy', def: '0'))! + + ? parseDoubleWithUnits(y, fontSize: fontSize)! + : parseDoubleWithUnits( + parserState.attribute('dy', def: '0'), + fontSize: fontSize, + )! + (lastOffset?.dy ?? 0), ); } @@ -81,14 +89,18 @@ class _TextInfo { // ignore: avoid_classes_with_only_static_members class _Elements { static Future? svg(SvgParserState parserState, bool warningsAsErrors) { - final DrawableViewport? viewBox = parseViewBox(parserState.attributes); + final DrawableViewport? viewBox = parseViewBox( + parserState.attributes, + fontSize: parserState.fontSize, + ); + final String? id = parserState.attribute('id', def: ''); final Color? color = parseColor(parserState.attribute('color', def: null)) ?? // Fallback to the currentColor from theme if no color is defined // on the root SVG element. - parserState.theme?.currentColor; + parserState.theme.currentColor; // TODO(dnfield): Support nested SVG elements. https://github.com/dnfield/flutter_svg/issues/132 if (parserState._root != null) { @@ -123,6 +135,7 @@ class _Elements { viewBox!.viewBoxRect, null, currentColor: color, + fontSize: parserState.fontSize, ), color: color, ), @@ -142,6 +155,7 @@ class _Elements { viewBox.viewBoxRect, null, currentColor: color, + fontSize: parserState.fontSize, ), color: color, ); @@ -164,6 +178,7 @@ class _Elements { parserState.rootBounds, parent.style, currentColor: color, + fontSize: parserState.fontSize, ), transform: parseTransform(parserState.attribute('transform'))?.storage, color: color, @@ -191,6 +206,7 @@ class _Elements { null, parent.style, currentColor: color, + fontSize: parserState.fontSize, ), transform: parseTransform(parserState.attribute('transform'))?.storage, color: color, @@ -213,14 +229,21 @@ class _Elements { parserState.rootBounds, parent!.style, currentColor: parent.color, + fontSize: parserState.fontSize, ); final Matrix4 transform = parseTransform(parserState.attribute('transform')) ?? Matrix4.identity(); transform.translate( - parseDouble(parserState.attribute('x', def: '0')), - parseDouble(parserState.attribute('y', def: '0'))!, + parseDoubleWithUnits( + parserState.attribute('x', def: '0'), + fontSize: parserState.fontSize, + ), + parseDoubleWithUnits( + parserState.attribute('y', def: '0'), + fontSize: parserState.fontSize, + )!, ); final DrawableStyleable ref = @@ -277,6 +300,7 @@ class _Elements { SvgParserState parserState, bool warningsAsErrors, ) { + final double fontSize = parserState.fontSize; final String? gradientUnits = getAttribute( parserState.attributes, 'gradientUnits', @@ -327,24 +351,24 @@ class _Elements { cx = isPercentage(rawCx!) ? parsePercentage(rawCx) * parserState.rootBounds.width + parserState.rootBounds.left - : parseDouble(rawCx)!; + : parseDoubleWithUnits(rawCx, fontSize: fontSize)!; cy = isPercentage(rawCy!) ? parsePercentage(rawCy) * parserState.rootBounds.height + parserState.rootBounds.top - : parseDouble(rawCy)!; + : parseDoubleWithUnits(rawCy, fontSize: fontSize)!; r = isPercentage(rawR!) ? parsePercentage(rawR) * ((parserState.rootBounds.height + parserState.rootBounds.width) / 2) - : parseDouble(rawR)!; + : parseDoubleWithUnits(rawR, fontSize: fontSize)!; fx = isPercentage(rawFx!) ? parsePercentage(rawFx) * parserState.rootBounds.width + parserState.rootBounds.left - : parseDouble(rawFx)!; + : parseDoubleWithUnits(rawFx, fontSize: fontSize)!; fy = isPercentage(rawFy!) ? parsePercentage(rawFy) * parserState.rootBounds.height + parserState.rootBounds.top - : parseDouble(rawFy)!; + : parseDoubleWithUnits(rawFy, fontSize: fontSize)!; } parserState._definitions.addGradient( @@ -368,6 +392,7 @@ class _Elements { static Future? linearGradient( SvgParserState parserState, bool warningsAsErrors) { + final double fontSize = parserState.fontSize; final String? gradientUnits = getAttribute( parserState.attributes, 'gradientUnits', @@ -420,22 +445,22 @@ class _Elements { isPercentage(x1!) ? parsePercentage(x1) * parserState.rootBounds.width + parserState.rootBounds.left - : parseDouble(x1)!, + : parseDoubleWithUnits(x1, fontSize: fontSize)!, isPercentage(y1!) ? parsePercentage(y1) * parserState.rootBounds.height + parserState.rootBounds.top - : parseDouble(y1)!, + : parseDoubleWithUnits(y1, fontSize: fontSize)!, ); toOffset = Offset( isPercentage(x2!) ? parsePercentage(x2) * parserState.rootBounds.width + parserState.rootBounds.left - : parseDouble(x2)!, + : parseDoubleWithUnits(x2, fontSize: fontSize)!, isPercentage(y2!) ? parsePercentage(y2) * parserState.rootBounds.height + parserState.rootBounds.top - : parseDouble(y2)!, + : parseDoubleWithUnits(y2, fontSize: fontSize)!, ); } @@ -472,7 +497,7 @@ class _Elements { if (pathFn != null) { final Path nextPath = applyTransformIfNeeded( - pathFn(parserState.attributes), + pathFn(parserState.attributes, parserState.fontSize), parserState.attributes, )!; nextPath.fillType = @@ -530,17 +555,30 @@ class _Elements { static Future image( SvgParserState parserState, bool warningsAsErrors) async { + final double fontSize = parserState.fontSize; final String? href = getHrefAttribute(parserState.attributes); if (href == null) { return; } final Offset offset = Offset( - parseDouble(parserState.attribute('x', def: '0'))!, - parseDouble(parserState.attribute('y', def: '0'))!, + parseDoubleWithUnits( + parserState.attribute('x', def: '0'), + fontSize: fontSize, + )!, + parseDoubleWithUnits( + parserState.attribute('y', def: '0'), + fontSize: fontSize, + )!, ); final Size size = Size( - parseDouble(parserState.attribute('width', def: '0'))!, - parseDouble(parserState.attribute('height', def: '0'))!, + parseDoubleWithUnits( + parserState.attribute('width', def: '0'), + fontSize: fontSize, + )!, + parseDoubleWithUnits( + parserState.attribute('height', def: '0'), + fontSize: fontSize, + )!, ); final Image image = await resolveImage(href); final DrawableParent parent = parserState._parentDrawables.last.drawable!; @@ -556,6 +594,7 @@ class _Elements { parserState.rootBounds, parentStyle, currentColor: parent.color, + fontSize: parserState.fontSize, ), size: size, transform: parseTransform(parserState.attribute('transform'))?.storage, @@ -631,13 +670,17 @@ class _Elements { } } + final DrawableStyle? parentStyle = + lastTextInfo?.style ?? parserState.currentGroup!.style; + textInfos.add(_TextInfo( parseStyle( parserState._key, parserState.attributes, parserState._definitions, parserState.rootBounds, - lastTextInfo?.style ?? parserState.currentGroup!.style, + parentStyle, + fontSize: parserState.fontSize, ), currentOffset, transform, @@ -672,24 +715,45 @@ class _Elements { // ignore: avoid_classes_with_only_static_members class _Paths { - static Path circle(Map attributes) { - final double cx = parseDouble(getAttribute(attributes, 'cx', def: '0'))!; - final double cy = parseDouble(getAttribute(attributes, 'cy', def: '0'))!; - final double r = parseDouble(getAttribute(attributes, 'r', def: '0'))!; + static Path circle(Map attributes, double fontSize) { + final double cx = parseDoubleWithUnits( + getAttribute(attributes, 'cx', def: '0'), + fontSize: fontSize, + )!; + final double cy = parseDoubleWithUnits( + getAttribute(attributes, 'cy', def: '0'), + fontSize: fontSize, + )!; + final double r = parseDoubleWithUnits( + getAttribute(attributes, 'r', def: '0'), + fontSize: fontSize, + )!; final Rect oval = Rect.fromCircle(center: Offset(cx, cy), radius: r); return Path()..addOval(oval); } - static Path path(Map attributes) { + static Path path(Map attributes, double fontSize) { final String d = getAttribute(attributes, 'd')!; return parseSvgPathData(d); } - static Path rect(Map attributes) { - final double x = parseDouble(getAttribute(attributes, 'x', def: '0'))!; - final double y = parseDouble(getAttribute(attributes, 'y', def: '0'))!; - final double w = parseDouble(getAttribute(attributes, 'width', def: '0'))!; - final double h = parseDouble(getAttribute(attributes, 'height', def: '0'))!; + static Path rect(Map attributes, double fontSize) { + final double x = parseDoubleWithUnits( + getAttribute(attributes, 'x', def: '0'), + fontSize: fontSize, + )!; + final double y = parseDoubleWithUnits( + getAttribute(attributes, 'y', def: '0'), + fontSize: fontSize, + )!; + final double w = parseDoubleWithUnits( + getAttribute(attributes, 'width', def: '0'), + fontSize: fontSize, + )!; + final double h = parseDoubleWithUnits( + getAttribute(attributes, 'height', def: '0'), + fontSize: fontSize, + )!; final Rect rect = Rect.fromLTWH(x, y, w, h); String? rxRaw = getAttribute(attributes, 'rx', def: null); String? ryRaw = getAttribute(attributes, 'ry', def: null); @@ -697,8 +761,14 @@ class _Paths { ryRaw ??= rxRaw; if (rxRaw != null && rxRaw != '') { - final double rx = parseDouble(rxRaw)!; - final double ry = parseDouble(ryRaw)!; + final double rx = parseDoubleWithUnits( + rxRaw, + fontSize: fontSize, + )!; + final double ry = parseDoubleWithUnits( + ryRaw, + fontSize: fontSize, + )!; return Path()..addRRect(RRect.fromRectXY(rect, rx, ry)); } @@ -706,11 +776,11 @@ class _Paths { return Path()..addRect(rect); } - static Path? polygon(Map attributes) { + static Path? polygon(Map attributes, double fontSize) { return parsePathFromPoints(attributes, true); } - static Path? polyline(Map attributes) { + static Path? polyline(Map attributes, double fontSize) { return parsePathFromPoints(attributes, false); } @@ -724,21 +794,45 @@ class _Paths { return parseSvgPathData(path); } - static Path ellipse(Map attributes) { - final double cx = parseDouble(getAttribute(attributes, 'cx', def: '0'))!; - final double cy = parseDouble(getAttribute(attributes, 'cy', def: '0'))!; - final double rx = parseDouble(getAttribute(attributes, 'rx', def: '0'))!; - final double ry = parseDouble(getAttribute(attributes, 'ry', def: '0'))!; + static Path ellipse(Map attributes, double fontSize) { + final double cx = parseDoubleWithUnits( + getAttribute(attributes, 'cx', def: '0'), + fontSize: fontSize, + )!; + final double cy = parseDoubleWithUnits( + getAttribute(attributes, 'cy', def: '0'), + fontSize: fontSize, + )!; + final double rx = parseDoubleWithUnits( + getAttribute(attributes, 'rx', def: '0'), + fontSize: fontSize, + )!; + final double ry = parseDoubleWithUnits( + getAttribute(attributes, 'ry', def: '0'), + fontSize: fontSize, + )!; final Rect r = Rect.fromLTWH(cx - rx, cy - ry, rx * 2, ry * 2); return Path()..addOval(r); } - static Path line(Map attributes) { - final double x1 = parseDouble(getAttribute(attributes, 'x1', def: '0'))!; - final double x2 = parseDouble(getAttribute(attributes, 'x2', def: '0'))!; - final double y1 = parseDouble(getAttribute(attributes, 'y1', def: '0'))!; - final double y2 = parseDouble(getAttribute(attributes, 'y2', def: '0'))!; + static Path line(Map attributes, double fontSize) { + final double x1 = parseDoubleWithUnits( + getAttribute(attributes, 'x1', def: '0'), + fontSize: fontSize, + )!; + final double x2 = parseDoubleWithUnits( + getAttribute(attributes, 'x2', def: '0'), + fontSize: fontSize, + )!; + final double y1 = parseDoubleWithUnits( + getAttribute(attributes, 'y1', def: '0'), + fontSize: fontSize, + )!; + final double y2 = parseDoubleWithUnits( + getAttribute(attributes, 'y2', def: '0'), + fontSize: fontSize, + )!; return Path() ..moveTo(x1, y1) @@ -768,8 +862,8 @@ class SvgParserState { : assert(events != null), _eventIterator = events.iterator; - /// A theme used when parsing SVG elements. - final SvgTheme? theme; + /// The theme used when parsing SVG elements. + final SvgTheme theme; final Iterator _eventIterator; final String? _key; @@ -917,7 +1011,7 @@ class SvgParserState { final DrawableParent parent = _parentDrawables.last.drawable!; final DrawableStyle? parentStyle = parent.style; - final Path path = pathFunc(attributes)!; + final Path path = pathFunc(attributes, fontSize)!; final DrawableStyleable drawable = DrawableShape( getAttribute(attributes, 'id', def: ''), path, @@ -929,6 +1023,7 @@ class SvgParserState { parentStyle, defaultFillColor: colorBlack, currentColor: parent.color, + fontSize: fontSize, ), transform: parseTransform(getAttribute(attributes, 'transform'))?.storage, ); @@ -993,3 +1088,8 @@ class SvgParserState { } } } + +extension on SvgParserState { + /// Retrieves the font size of the current [theme]. + double get fontSize => theme.fontSize; +} diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index ce39f759b9d2..36e89e87ac0c 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -20,12 +20,22 @@ final Map _kTextSizeMap = { }; /// Parses a `font-size` attribute. -double? parseFontSize(String? raw, {double? parentValue}) { +/// +/// Uses [fontSize] to calculate the font size including em units. +double? parseFontSize( + String? raw, { + required double fontSize, + double? parentValue, +}) { if (raw == null || raw == '') { return null; } - double? ret = parseDouble(raw, tryParse: true); + double? ret = parseDoubleWithUnits( + raw, + tryParse: true, + fontSize: fontSize, + ); if (ret != null) { return ret; } diff --git a/third_party/lib/src/svg/theme.dart b/third_party/lib/src/svg/theme.dart index 49eb71e637b4..1cde53d9a864 100644 --- a/third_party/lib/src/svg/theme.dart +++ b/third_party/lib/src/svg/theme.dart @@ -5,23 +5,33 @@ import 'package:meta/meta.dart'; /// A theme used when decoding an SVG picture. @immutable class SvgTheme { - /// Instantiates an SVG theme with the [currentColor]. + /// Instantiates an SVG theme with the [currentColor] + /// and [fontSize]. + /// + /// Defaults the [fontSize] to 14. const SvgTheme({ this.currentColor, + this.fontSize = 14, }); /// The default color applied to SVG elements that inherit the color property. /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword final Color? currentColor; + /// The font size used when calculating em units of SVG elements. + /// See: https://www.w3.org/TR/SVG11/coords.html#Units + final double fontSize; + @override bool operator ==(dynamic other) { if (other.runtimeType != runtimeType) { return false; } - return other is SvgTheme && currentColor == other.currentColor; + return other is SvgTheme && + currentColor == other.currentColor && + fontSize == other.fontSize; } @override - int get hashCode => currentColor.hashCode; + int get hashCode => hashValues(currentColor, fontSize); } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index d46d987ba676..de53a91f89e3 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -10,23 +10,29 @@ import '../vector_drawable.dart'; import 'colors.dart'; import 'parsers.dart'; -double _parseRawWidthHeight(String? raw) { +double _parseRawWidthHeight( + String? raw, { + required double fontSize, +}) { if (raw == '100%' || raw == '') { return double.infinity; } assert(() { final RegExp notDigits = RegExp(r'[^\d\.]'); - if (!raw!.endsWith('px') && raw.contains(notDigits)) { + if (!raw!.endsWith('px') && + !raw.endsWith('em') && + raw.contains(notDigits)) { print( 'Warning: Flutter SVG only supports the following formats for `width` and `height` on the SVG root:\n' ' width="100%"\n' + ' width="100em"\n' ' width="100px"\n' ' width="100" (where the number will be treated as pixels).\n' 'The supplied value ($raw) will be discarded and treated as if it had not been specified.'); } return true; }()); - return double.tryParse(raw!.replaceAll('px', '')) ?? double.infinity; + return parseDoubleWithUnits(raw, fontSize: fontSize) ?? double.infinity; } /// Parses an SVG @viewBox attribute (e.g. 0 0 100 100) to a [Rect]. @@ -38,6 +44,7 @@ double _parseRawWidthHeight(String? raw) { /// on the root SVG element should be treated in accordance with the specification. DrawableViewport? parseViewBox( Map svg, { + required double fontSize, bool nullOk = false, }) { final String? viewBox = getAttribute(svg, 'viewBox'); @@ -56,8 +63,15 @@ DrawableViewport? parseViewBox( ' $svg'); } - final double width = _parseRawWidthHeight(rawWidth); - final double height = _parseRawWidthHeight(rawHeight); + final double width = _parseRawWidthHeight( + rawWidth, + fontSize: fontSize, + ); + + final double height = _parseRawWidthHeight( + rawHeight, + fontSize: fontSize, + ); if (viewBox == '') { return DrawableViewport( @@ -111,8 +125,9 @@ TileMode parseTileMode(Map attributes) { /// /// Does not currently support percentages. CircularIntervalList? parseDashArray( - Map attributes, -) { + Map attributes, { + required double fontSize, +}) { final String? rawDashArray = getAttribute(attributes, 'stroke-dasharray'); if (rawDashArray == '') { return null; @@ -121,24 +136,28 @@ CircularIntervalList? parseDashArray( } final List parts = rawDashArray!.split(RegExp(r'[ ,]+')); - return CircularIntervalList( - parts.map((String part) => parseDouble(part)!).toList()); + return CircularIntervalList(parts + .map((String part) => parseDoubleWithUnits(part, fontSize: fontSize)!) + .toList()); } /// Parses a @stroke-dashoffset into a [DashOffset]. -DashOffset? parseDashOffset(Map attributes) { +DashOffset? parseDashOffset( + Map attributes, { + required double fontSize, +}) { final String? rawDashOffset = getAttribute(attributes, 'stroke-dashoffset'); if (rawDashOffset == '') { return null; } if (rawDashOffset!.endsWith('%')) { - final double percentage = - parseDouble(rawDashOffset.substring(0, rawDashOffset.length - 1))! / - 100; - return DashOffset.percentage(percentage); + return DashOffset.percentage(parsePercentage(rawDashOffset)); } else { - return DashOffset.absolute(parseDouble(rawDashOffset)!); + return DashOffset.absolute(parseDoubleWithUnits( + rawDashOffset, + fontSize: fontSize, + )!); } } @@ -179,6 +198,7 @@ DrawablePaint? parseStroke( DrawableDefinitionServer definitions, DrawablePaint? parentStroke, Color? currentColor, + double fontSize, ) { final String rawStroke = getAttribute(attributes, 'stroke')!; final String? rawStrokeOpacity = getAttribute( @@ -240,7 +260,10 @@ DrawablePaint? parseStroke( : parseDouble(rawMiterLimit), strokeWidth: rawStrokeWidth == '' ? parentStroke?.strokeWidth ?? 1.0 - : parseDouble(rawStrokeWidth), + : parseDoubleWithUnits( + rawStrokeWidth, + fontSize: fontSize, + ), ); return paint; } @@ -474,6 +497,7 @@ DrawableStyle parseStyle( DrawableDefinitionServer definitions, Rect? bounds, DrawableStyle? parentStyle, { + required double fontSize, Color? defaultFillColor, Color? currentColor, }) { @@ -486,9 +510,16 @@ DrawableStyle parseStyle( definitions, parentStyle?.stroke, currentColor, + fontSize, + ), + dashArray: parseDashArray( + attributes, + fontSize: fontSize, + ), + dashOffset: parseDashOffset( + attributes, + fontSize: fontSize, ), - dashArray: parseDashArray(attributes), - dashOffset: parseDashOffset(attributes), fill: parseFill( key, attributes, @@ -511,6 +542,7 @@ DrawableStyle parseStyle( fontSize: parseFontSize( getAttribute(attributes, 'font-size'), parentValue: parentStyle?.textStyle?.fontSize, + fontSize: fontSize, ), fontWeight: parseFontWeight( getAttribute(attributes, 'font-weight', def: null), diff --git a/third_party/lib/src/utilities/numbers.dart b/third_party/lib/src/utilities/numbers.dart index fc3e174475f4..1b3f2f1ac26c 100644 --- a/third_party/lib/src/utilities/numbers.dart +++ b/third_party/lib/src/utilities/numbers.dart @@ -1,16 +1,51 @@ -/// Parses a `String` to a `double`. +/// Parses a [rawDouble] `String` to a `double`. /// -/// Passing `null` will return `null`. +/// The [rawDouble] might include a unit (`px` or `em`) +/// which is stripped off when parsed to a `double`. /// -/// Will strip off a `px` prefix. -double? parseDouble(String? maybeDouble, {bool tryParse = false}) { +/// Passing `null` will return `null`. +double? parseDouble(String? rawDouble, {bool tryParse = false}) { assert(tryParse != null); // ignore: unnecessary_null_comparison - if (maybeDouble == null) { + if (rawDouble == null) { return null; } - maybeDouble = maybeDouble.replaceFirst('px', '').trim(); + + rawDouble = rawDouble.replaceFirst('em', '').replaceFirst('px', '').trim(); + if (tryParse) { - return double.tryParse(maybeDouble); + return double.tryParse(rawDouble); + } + return double.parse(rawDouble); +} + +/// Parses a [rawDouble] `String` to a `double` +/// taking into account absolute and relative units +/// (`px` or `em`). +/// +/// Passing an `em` value will calculate the result +/// relative to the provided [fontSize]: +/// 1 em = 1 * [fontSize]. +/// +/// The [rawDouble] might include a unit which is +/// stripped off when parsed to a `double`. +/// +/// Passing `null` will return `null`. +double? parseDoubleWithUnits( + String? rawDouble, { + required double fontSize, + bool tryParse = false, +}) { + double unit = 1.0; + + // 1 em unit is equal to the current font size. + if (rawDouble?.contains('em') ?? false) { + unit = fontSize; } - return double.parse(maybeDouble); + + final double? value = parseDouble( + rawDouble, + tryParse: tryParse, + ); + + return value != null ? value * unit : null; } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index ec1d11a9938a..b02018242977 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -43,6 +43,9 @@ class Svg { /// /// The `colorFilter` property will be applied to any [Paint] objects used during drawing. /// + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. + /// /// The [key] will be used for debugging purposes. Future svgPictureDecoder( Uint8List raw, @@ -72,6 +75,9 @@ class Svg { /// /// The `colorFilter` property will be applied to any [Paint] objects used during drawing. /// + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. + /// /// The [key] will be used for debugging purposes. Future svgPictureStringDecoder( String raw, @@ -235,7 +241,7 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, - this.currentColor, + this.theme, }) : super(key: key); /// Instantiates a widget that renders an SVG picture from an [AssetBundle]. @@ -264,8 +270,8 @@ class SvgPicture extends StatefulWidget { /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. /// - /// The `currentColor` argument, if provided, will override the default color - /// of any SVG element that inherits its color. + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. /// /// ## Assets in packages /// @@ -336,7 +342,7 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, - this.currentColor, + this.theme, }) : pictureProvider = ExactAssetPicture( allowDrawingOutsideViewBox == true ? svgStringDecoderOutsideViewBoxBuilder @@ -374,8 +380,8 @@ class SvgPicture extends StatefulWidget { /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. /// - /// The `currentColor` argument, if provided, will override the default color - /// of any SVG element that inherits its color. + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. /// /// All network images are cached regardless of HTTP headers. /// @@ -400,7 +406,7 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, - this.currentColor, + this.theme, }) : pictureProvider = NetworkPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBoxBuilder @@ -437,8 +443,8 @@ class SvgPicture extends StatefulWidget { /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. /// - /// The `currentColor` argument, if provided, will override the default color - /// of any SVG element that inherits its color. + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. /// /// On Android, this may require the /// `android.permission.READ_EXTERNAL_STORAGE` permission. @@ -460,7 +466,7 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, - this.currentColor, + this.theme, }) : pictureProvider = FilePicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBoxBuilder @@ -496,8 +502,8 @@ class SvgPicture extends StatefulWidget { /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. /// - /// The `currentColor` argument, if provided, will override the default color - /// of any SVG element that inherits its color. + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. /// /// If [excludeFromSemantics] is true, then [semanticLabel] will be ignored. SvgPicture.memory( @@ -516,7 +522,7 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, - this.currentColor, + this.theme, }) : pictureProvider = MemoryPicture( allowDrawingOutsideViewBox == true ? svgByteDecoderOutsideViewBoxBuilder @@ -552,8 +558,8 @@ class SvgPicture extends StatefulWidget { /// The `color` and `colorBlendMode` arguments, if specified, will be used to set a /// [ColorFilter] on any [Paint]s created for this drawing. /// - /// The `currentColor` argument, if provided, will override the default color - /// of any SVG element that inherits its color. + /// The `theme` argument, if provided, will override the default theme + /// used when parsing SVG elements. /// /// If [excludeFromSemantics] is true, then [semanticLabel] will be ignored. SvgPicture.string( @@ -572,7 +578,7 @@ class SvgPicture extends StatefulWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, this.cacheColorFilter = false, - this.currentColor, + this.theme, }) : pictureProvider = StringPicture( allowDrawingOutsideViewBox == true ? svgStringDecoderOutsideViewBoxBuilder @@ -595,50 +601,49 @@ class SvgPicture extends StatefulWidget { /// A [PictureInfoDecoderBuilder] for [Uint8List]s that will clip to the viewBox. static final PictureInfoDecoderBuilder svgByteDecoderBuilder = - (Color? currentColor) => + (SvgTheme theme) => (Uint8List bytes, ColorFilter? colorFilter, String key) => svg.svgPictureDecoder( bytes, false, colorFilter, key, - theme: SvgTheme(currentColor: currentColor), + theme: theme, ); /// A [PictureInfoDecoderBuilder] for strings that will clip to the viewBox. static final PictureInfoDecoderBuilder svgStringDecoderBuilder = - (Color? currentColor) => - (String data, ColorFilter? colorFilter, String key) => - svg.svgPictureStringDecoder( - data, - false, - colorFilter, - key, - theme: SvgTheme(currentColor: currentColor), - ); + (SvgTheme theme) => (String data, ColorFilter? colorFilter, String key) => + svg.svgPictureStringDecoder( + data, + false, + colorFilter, + key, + theme: theme, + ); /// A [PictureInfoDecoderBuilder] for [Uint8List]s that will not clip to the viewBox. static final PictureInfoDecoderBuilder - svgByteDecoderOutsideViewBoxBuilder = (Color? currentColor) => + svgByteDecoderOutsideViewBoxBuilder = (SvgTheme theme) => (Uint8List bytes, ColorFilter? colorFilter, String key) => svg.svgPictureDecoder( bytes, true, colorFilter, key, - theme: SvgTheme(currentColor: currentColor), + theme: theme, ); /// A [PictureInfoDecoderBuilder] for [String]s that will not clip to the viewBox. static final PictureInfoDecoderBuilder - svgStringDecoderOutsideViewBoxBuilder = (Color? currentColor) => + svgStringDecoderOutsideViewBoxBuilder = (SvgTheme theme) => (String data, ColorFilter? colorFilter, String key) => svg.svgPictureStringDecoder( data, true, colorFilter, key, - theme: SvgTheme(currentColor: currentColor), + theme: theme, ); /// If specified, the width to use for the SVG. If unspecified, the SVG @@ -725,9 +730,8 @@ class SvgPicture extends StatefulWidget { /// This defaults to false and must not be null. final bool cacheColorFilter; - /// The default color applied to SVG elements that inherit the color property. - /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword - final Color? currentColor; + /// The theme used when parsing SVG elements. + final SvgTheme? theme; @override State createState() => _SvgPictureState(); @@ -762,12 +766,31 @@ class _SvgPictureState extends State { super.reassemble(); } - /// Updates the `currentColor` of the picture provider based on either - /// the widget's `currentColor` property or [DefaultSvgTheme]. + /// Updates the `currentColor` of the picture provider based on + /// either the widget's [SvgTheme] or an inherited [DefaultSvgTheme]. + /// + /// Updates the `fontSize` of the picture provider based on + /// either the widget's [SvgTheme], an inherited [DefaultSvgTheme] + /// or an inherited [DefaultTextStyle]. If the property does not exist, + /// then the font size defaults to 14. void _updatePictureProvider() { - final SvgTheme? svgTheme = DefaultSvgTheme.of(context)?.theme; - final Color? currentColor = widget.currentColor ?? svgTheme?.currentColor; - widget.pictureProvider.currentColor = currentColor; + final SvgTheme? defaultSvgTheme = DefaultSvgTheme.of(context)?.theme; + final TextStyle defaultTextStyle = DefaultTextStyle.of(context).style; + + final Color? currentColor = + widget.theme?.currentColor ?? defaultSvgTheme?.currentColor; + + final double fontSize = widget.theme?.fontSize ?? + defaultSvgTheme?.fontSize ?? + defaultTextStyle.fontSize ?? + // Fallback to the default font size if a font size is missing in DefaultTextStyle. + // See: https://api.flutter.dev/flutter/painting/TextStyle/fontSize.html + 14.0; + + widget.pictureProvider.theme = SvgTheme( + currentColor: currentColor, + fontSize: fontSize, + ); } void _resolveImage() { diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 465f037a8783..a1819e04c986 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -7,7 +7,7 @@ dependencies: flutter: sdk: flutter meta: ^1.3.0 - path_drawing: ^0.5.1 + path_drawing: ^0.5.1+1 vector_math: ^2.1.0 xml: ^5.0.0 diff --git a/third_party/test/default_theme_test.dart b/third_party/test/default_theme_test.dart index 5680a75762c9..2ee9dc9877dd 100644 --- a/third_party/test/default_theme_test.dart +++ b/third_party/test/default_theme_test.dart @@ -2,6 +2,7 @@ import 'dart:ui'; +import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -10,11 +11,12 @@ void main() { testWidgets('changes propagate to SvgPicture', (WidgetTester tester) async { const SvgTheme svgTheme = SvgTheme( currentColor: Color(0xFF733821), + fontSize: 14.0, ); final SvgPicture svgPictureWidget = SvgPicture.string(''' - + '''); await tester.pumpWidget(DefaultSvgTheme( @@ -25,12 +27,13 @@ void main() { SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); expect(svgPicture, isNotNull); expect( - svgPicture.pictureProvider.currentColor, - equals(svgTheme.currentColor), + svgPicture.pictureProvider.theme, + equals(svgTheme), ); const SvgTheme anotherSvgTheme = SvgTheme( currentColor: Color(0xFF05290E), + fontSize: 12.0, ); await tester.pumpWidget(DefaultSvgTheme( @@ -41,16 +44,17 @@ void main() { svgPicture = tester.firstWidget(find.byType(SvgPicture)); expect(svgPicture, isNotNull); expect( - svgPicture.pictureProvider.currentColor, - equals(anotherSvgTheme.currentColor), + svgPicture.pictureProvider.theme, + equals(anotherSvgTheme), ); }); testWidgets( - 'currentColor widget property takes precedence over ' + 'currentColor from the widget\'s theme takes precedence over ' 'the theme from DefaultSvgTheme', (WidgetTester tester) async { const SvgTheme svgTheme = SvgTheme( currentColor: Color(0xFF733821), + fontSize: 14.0, ); final SvgPicture svgPictureWidget = SvgPicture.string( @@ -58,7 +62,10 @@ void main() { ''', - currentColor: Color(0xFF05290E), + theme: SvgTheme( + currentColor: Color(0xFF05290E), + fontSize: 14.0, + ), ); await tester.pumpWidget(DefaultSvgTheme( @@ -69,9 +76,86 @@ void main() { final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); expect(svgPicture, isNotNull); expect( - svgPicture.pictureProvider.currentColor, + svgPicture.pictureProvider.theme.currentColor, equals(Color(0xFF05290E)), ); }); + + testWidgets( + 'fontSize from the widget\'s theme takes precedence over ' + 'the theme from DefaultSvgTheme', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + fontSize: 14.0, + ); + + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + theme: SvgTheme( + fontSize: 12.0, + ), + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + svgPicture.pictureProvider.theme.fontSize, + equals(12.0), + ); + }); + + testWidgets( + 'fontSize defaults to the font size from DefaultTextStyle ' + 'if no widget\'s theme or DefaultSvgTheme is provided', + (WidgetTester tester) async { + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + ); + + await tester.pumpWidget( + DefaultTextStyle( + style: TextStyle(fontSize: 26.0), + child: svgPictureWidget, + ), + ); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + svgPicture.pictureProvider.theme.fontSize, + equals(26.0), + ); + }); + + testWidgets( + 'fontSize defaults to 14 ' + 'if no widget\'s theme, DefaultSvgTheme or DefaultTextStyle is provided', + (WidgetTester tester) async { + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + ); + + await tester.pumpWidget(svgPictureWidget); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + svgPicture.pictureProvider.theme.fontSize, + equals(14.0), + ); + }); }); } diff --git a/third_party/test/error_test.dart b/third_party/test/error_test.dart index 97e5220c6fd0..c4d2c9b61046 100644 --- a/third_party/test/error_test.dart +++ b/third_party/test/error_test.dart @@ -23,7 +23,10 @@ void main() { '''; final SvgParser parser = SvgParser(); - await parser.parse(svgStr, key: 'some_svg.svg'); + await parser.parse( + svgStr, + key: 'some_svg.svg', + ); expect( error.context.toString(), diff --git a/third_party/test/golden_widget/circle.em.png b/third_party/test/golden_widget/circle.em.png new file mode 100644 index 0000000000000000000000000000000000000000..b25ef06cfb940ee7bd201e48bdd5aa440269056a GIT binary patch literal 10223 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 E08E}cL;wH) literal 0 HcmV?d00001 diff --git a/third_party/test/golden_widget/ellipse.em.png b/third_party/test/golden_widget/ellipse.em.png new file mode 100644 index 0000000000000000000000000000000000000000..ce31c666904280716471bcd8b3b654b2c55787f6 GIT binary patch literal 6672 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 I8~LgK1wH#CDgXcg literal 0 HcmV?d00001 diff --git a/third_party/test/picture_cache_test.dart b/third_party/test/picture_cache_test.dart index cfdda243139e..b0358fd58b84 100644 --- a/third_party/test/picture_cache_test.dart +++ b/third_party/test/picture_cache_test.dart @@ -1,6 +1,7 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/src/picture_cache.dart'; +import 'package:flutter_svg/src/svg/theme.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:xml/xml.dart'; @@ -73,11 +74,16 @@ void main() { ); expect(PictureProvider.cache.count, 0); + + final PictureProvider pictureProvider = StringPicture( + SvgPicture.svgStringDecoderBuilder, + svgString, + )..theme = const SvgTheme( + fontSize: 14.0, + ); + await precachePicture( - StringPicture( - SvgPicture.svgStringDecoderBuilder, - svgString, - ), + pictureProvider, tester.element(find.text('test_text')), ); expect(PictureProvider.cache.count, 1); @@ -133,11 +139,16 @@ void main() { expect(error, isInstanceOf()); } + final PictureProvider pictureProvider = StringPicture( + SvgPicture.svgStringDecoderBuilder, + svgString, + )..theme = const SvgTheme( + currentColor: Color(0xFF05290E), + fontSize: 14.0, + ); + await precachePicture( - StringPicture( - SvgPicture.svgStringDecoderBuilder, - svgString, - ), + pictureProvider, tester.element(find.text('test_text')), onError: errorListener, ); diff --git a/third_party/test/picture_provider_test.dart b/third_party/test/picture_provider_test.dart index baedd2f46d6a..b72ac51fe274 100644 --- a/third_party/test/picture_provider_test.dart +++ b/third_party/test/picture_provider_test.dart @@ -1,8 +1,11 @@ +// ignore_for_file: prefer_const_constructors + import 'dart:io'; import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_svg/src/svg/theme.dart'; import 'package:mocktail/mocktail.dart'; import 'package:test/test.dart'; @@ -12,149 +15,211 @@ class MockFile extends Mock implements File {} void main() { group('PictureProvider', () { - Color? currentColor; + SvgTheme? currentTheme; - PictureInfoDecoder decoderBuilder(Color? color) { - currentColor = color; + PictureInfoDecoder decoderBuilder(SvgTheme theme) { + currentTheme = theme; return (T bytes, ColorFilter? colorFilter, String key) async => MockPictureInfo(); } - test( - 'NetworkPicture rebuilds the decoder using decoderBuilder ' - 'when currentColor changes', () async { - const Color color = Color(0xFFB0E3BE); - final NetworkPicture networkPicture = - NetworkPicture(decoderBuilder, 'url'); - - final PictureInfoDecoder decoder = networkPicture.decoder; - - expect(decoder, isNotNull); - - // Update the currentColor of PictureProvider. - networkPicture.currentColor = color; - - expect( - decoder, - isNot(equals(networkPicture.decoder)), - ); - - expect( - currentColor, - equals(color), - ); + group( + 'rebuilds the decoder using decoderBuilder ' + 'when currentColor changes', () { + test('NetworkPicture', () async { + const Color color = Color(0xFFB0E3BE); + final NetworkPicture networkPicture = + NetworkPicture(decoderBuilder, 'url') + ..theme = SvgTheme(fontSize: 14.0); + + final PictureInfoDecoder? decoder = networkPicture.decoder; + + // Update the theme of PictureProvider to include currentColor. + networkPicture.theme = SvgTheme( + currentColor: color, + fontSize: 14.0, + ); + + expect(networkPicture.decoder, isNotNull); + expect(networkPicture.decoder, isNot(equals(decoder))); + expect(currentTheme?.currentColor, equals(color)); + }); + + test('FilePicture', () async { + const Color color = Color(0xFFB0E3BE); + final FilePicture filePicture = FilePicture(decoderBuilder, MockFile()) + ..theme = SvgTheme(fontSize: 14.0); + + final PictureInfoDecoder? decoder = filePicture.decoder; + + // Update the theme of PictureProvider to include currentColor. + filePicture.theme = SvgTheme( + currentColor: color, + fontSize: 14.0, + ); + + expect(filePicture.decoder, isNotNull); + expect(filePicture.decoder, isNot(equals(decoder))); + expect(currentTheme?.currentColor, equals(color)); + }); + + test('MemoryPicture', () async { + const Color color = Color(0xFFB0E3BE); + final MemoryPicture memoryPicture = + MemoryPicture(decoderBuilder, Uint8List(0)) + ..theme = SvgTheme(fontSize: 14.0); + + final PictureInfoDecoder? decoder = memoryPicture.decoder; + + // Update the theme of PictureProvider to include currentColor. + memoryPicture.theme = SvgTheme( + currentColor: color, + fontSize: 14.0, + ); + + expect(memoryPicture.decoder, isNotNull); + expect(memoryPicture.decoder, isNot(equals(decoder))); + expect(currentTheme?.currentColor, equals(color)); + }); + + test('StringPicture', () async { + const Color color = Color(0xFFB0E3BE); + final StringPicture stringPicture = StringPicture(decoderBuilder, '') + ..theme = SvgTheme(fontSize: 14.0); + + final PictureInfoDecoder? decoder = stringPicture.decoder; + + // Update the theme of PictureProvider to include currentColor. + stringPicture.theme = SvgTheme( + currentColor: color, + fontSize: 14.0, + ); + + expect(stringPicture.decoder, isNotNull); + expect(stringPicture.decoder, isNot(equals(decoder))); + expect(currentTheme?.currentColor, equals(color)); + }); + + test('ExactAssetPicture', () async { + const Color color = Color(0xFFB0E3BE); + final ExactAssetPicture exactAssetPicture = + ExactAssetPicture(decoderBuilder, '') + ..theme = SvgTheme(fontSize: 14.0); + + final PictureInfoDecoder? decoder = exactAssetPicture.decoder; + + // Update the theme of PictureProvider to include currentColor. + exactAssetPicture.theme = SvgTheme( + currentColor: color, + fontSize: 14.0, + ); + + expect(exactAssetPicture.decoder, isNotNull); + expect(exactAssetPicture.decoder, isNot(equals(decoder))); + expect(currentTheme?.currentColor, equals(color)); + }); }); - test( - 'FilePicture rebuilds the decoder using decoderBuilder ' - 'when currentColor changes', () async { - const Color color = Color(0xFFB0E3BE); - final FilePicture filePicture = FilePicture(decoderBuilder, MockFile()); - - final PictureInfoDecoder decoder = filePicture.decoder; - - expect(decoder, isNotNull); - - // Update the currentColor of PictureProvider. - filePicture.currentColor = color; - - expect( - decoder, - isNot(equals(filePicture.decoder)), - ); - - expect( - currentColor, - equals(color), - ); + group( + 'rebuilds the decoder using decoderBuilder ' + 'when fontSize changes', () { + test('NetworkPicture', () async { + const double fontSize = 26.0; + final NetworkPicture networkPicture = + NetworkPicture(decoderBuilder, 'url'); + + final PictureInfoDecoder? decoder = networkPicture.decoder; + + // Update the theme of PictureProvider to include fontSize. + networkPicture.theme = SvgTheme( + fontSize: fontSize, + ); + + expect(networkPicture.decoder, isNotNull); + expect(networkPicture.decoder, isNot(equals(decoder))); + expect(currentTheme?.fontSize, equals(fontSize)); + }); + + test('FilePicture', () async { + const double fontSize = 26.0; + final FilePicture filePicture = FilePicture(decoderBuilder, MockFile()); + + final PictureInfoDecoder? decoder = filePicture.decoder; + + // Update the theme of PictureProvider to include fontSize. + filePicture.theme = SvgTheme( + fontSize: fontSize, + ); + + expect(filePicture.decoder, isNotNull); + expect(filePicture.decoder, isNot(equals(decoder))); + expect(currentTheme?.fontSize, equals(fontSize)); + }); + + test('MemoryPicture', () async { + const double fontSize = 26.0; + final MemoryPicture memoryPicture = + MemoryPicture(decoderBuilder, Uint8List(0)); + + final PictureInfoDecoder? decoder = memoryPicture.decoder; + + // Update the theme of PictureProvider to include fontSize. + memoryPicture.theme = SvgTheme( + fontSize: fontSize, + ); + + expect(memoryPicture.decoder, isNotNull); + expect(memoryPicture.decoder, isNot(equals(decoder))); + expect(currentTheme?.fontSize, equals(fontSize)); + }); + + test('StringPicture', () async { + const double fontSize = 26.0; + final StringPicture stringPicture = StringPicture(decoderBuilder, ''); + + final PictureInfoDecoder? decoder = stringPicture.decoder; + + // Update the theme of PictureProvider to include fontSize. + stringPicture.theme = SvgTheme( + fontSize: fontSize, + ); + + expect(stringPicture.decoder, isNotNull); + expect(stringPicture.decoder, isNot(equals(decoder))); + expect(currentTheme?.fontSize, equals(fontSize)); + }); + + test('ExactAssetPicture', () async { + const double fontSize = 26.0; + final ExactAssetPicture exactAssetPicture = + ExactAssetPicture(decoderBuilder, ''); + + final PictureInfoDecoder? decoder = exactAssetPicture.decoder; + + // Update the theme of PictureProvider to include fontSize. + exactAssetPicture.theme = SvgTheme( + fontSize: fontSize, + ); + + expect(exactAssetPicture.decoder, isNotNull); + expect(exactAssetPicture.decoder, isNot(equals(decoder))); + expect(currentTheme?.fontSize, equals(fontSize)); + }); }); - test( - 'MemoryPicture rebuilds the decoder using decoderBuilder ' - 'when currentColor changes', () async { - const Color color = Color(0xFFB0E3BE); - final MemoryPicture memoryPicture = - MemoryPicture(decoderBuilder, Uint8List(0)); - - final PictureInfoDecoder decoder = memoryPicture.decoder; - - expect(decoder, isNotNull); - - // Update the currentColor of PictureProvider. - memoryPicture.currentColor = color; - - expect( - decoder, - isNot(equals(memoryPicture.decoder)), - ); - - expect( - currentColor, - equals(color), - ); - }); - - test( - 'StringPicture rebuilds the decoder using decoderBuilder ' - 'when currentColor changes', () async { - const Color color = Color(0xFFB0E3BE); - final StringPicture stringPicture = StringPicture(decoderBuilder, ''); - - final PictureInfoDecoder decoder = stringPicture.decoder; - - expect(decoder, isNotNull); - - // Update the currentColor of PictureProvider. - stringPicture.currentColor = color; - - expect( - decoder, - isNot(equals(stringPicture.decoder)), - ); - - expect( - currentColor, - equals(color), - ); - }); - - test( - 'ExactAssetPicture rebuilds the decoder using decoderBuilder ' - 'when currentColor changes', () async { - const Color color = Color(0xFFB0E3BE); - final ExactAssetPicture exactAssetPicture = - ExactAssetPicture(decoderBuilder, ''); - - final PictureInfoDecoder decoder = exactAssetPicture.decoder; - - expect(decoder, isNotNull); - - // Update the currentColor of PictureProvider. - exactAssetPicture.currentColor = color; - - expect( - decoder, - isNot(equals(exactAssetPicture.decoder)), - ); - - expect( - currentColor, - equals(color), - ); - }); - - test('Evicts from cache when currentColor changes', () async { + test('Evicts from cache when theme changes', () async { expect(PictureProvider.cache.count, 0); const Color color = Color(0xFFB0E3BE); final StringPicture stringPicture = StringPicture(decoderBuilder, ''); - final PictureStream stream = + final PictureStream _ = stringPicture.resolve(createLocalPictureConfiguration(null)); await null; expect(PictureProvider.cache.count, 1); - stringPicture.currentColor = color; + stringPicture.theme = SvgTheme(currentColor: color); + expect(PictureProvider.cache.count, 0); }); }); diff --git a/third_party/test/svg_parsers_test.dart b/third_party/test/svg_parsers_test.dart index 60614f43ae9c..0472f62040be 100644 --- a/third_party/test/svg_parsers_test.dart +++ b/third_party/test/svg_parsers_test.dart @@ -1,4 +1,4 @@ -import 'dart:ui' show Color, PathFillType; +import 'dart:ui' show Color, Offset, PathFillType, Size; import 'package:flutter_svg/parser.dart'; import 'package:flutter_svg/src/svg/parsers.dart'; @@ -113,29 +113,52 @@ void main() { } test('Font size parsing tests', () { - expect(parseFontSize(null), isNull); - expect(parseFontSize(''), isNull); - expect(parseFontSize('1'), 1); - expect(parseFontSize(' 1 '), 1); - expect(parseFontSize('xx-small'), 10); - expect(parseFontSize('x-small'), 12); - expect(parseFontSize('small'), 14); - expect(parseFontSize('medium'), 18); - expect(parseFontSize('large'), 22); - expect(parseFontSize('x-large'), 26); - expect(parseFontSize('xx-large'), 32); - - expect(parseFontSize('larger'), parseFontSize('large')); - expect(parseFontSize('larger', parentValue: parseFontSize('large')), - parseFontSize('large')! * 1.2); - expect(parseFontSize('smaller'), parseFontSize('small')); - expect(parseFontSize('smaller', parentValue: parseFontSize('large')), - parseFontSize('large')! / 1.2); - - expect(() => parseFontSize('invalid'), + const double fontSize = 14.0; + expect(parseFontSize(null, fontSize: fontSize), isNull); + expect(parseFontSize('', fontSize: fontSize), isNull); + expect(parseFontSize('1', fontSize: fontSize), 1); + expect(parseFontSize(' 1 ', fontSize: fontSize), 1); + expect(parseFontSize('xx-small', fontSize: fontSize), 10); + expect(parseFontSize('x-small', fontSize: fontSize), 12); + expect(parseFontSize('small', fontSize: fontSize), 14); + expect(parseFontSize('medium', fontSize: fontSize), 18); + expect(parseFontSize('large', fontSize: fontSize), 22); + expect(parseFontSize('x-large', fontSize: fontSize), 26); + expect(parseFontSize('xx-large', fontSize: fontSize), 32); + + expect(parseFontSize('larger', fontSize: fontSize), + parseFontSize('large', fontSize: fontSize)); + expect( + parseFontSize('larger', + fontSize: fontSize, + parentValue: parseFontSize('large', fontSize: fontSize)), + parseFontSize('large', fontSize: fontSize)! * 1.2); + expect(parseFontSize('smaller', fontSize: fontSize), + parseFontSize('small', fontSize: fontSize)); + expect( + parseFontSize('smaller', + fontSize: fontSize, + parentValue: parseFontSize('large', fontSize: fontSize)), + parseFontSize('large', fontSize: fontSize)! / 1.2); + + expect(() => parseFontSize('invalid', fontSize: fontSize), throwsA(const TypeMatcher())); }); + test('relative font size tests', () { + const double fontSize = 26.0; + + expect( + parseFontSize('4em', fontSize: fontSize), + equals(4 * fontSize), + ); + + expect( + parseFontSize(' 2em ', fontSize: fontSize), + equals(2 * fontSize), + ); + }); + test('Check no child with id for svg', () async { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse( @@ -200,6 +223,7 @@ void main() { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse(svgStr); + expect(root.id!.isEmpty, true); expect(find(root, 'Page-1') != null, true); expect(find(root, 'iPhone-8') != null, true); @@ -290,7 +314,10 @@ void main() { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse( svgStr, - theme: const SvgTheme(currentColor: currentColor), + theme: const SvgTheme( + currentColor: currentColor, + fontSize: 14.0, + ), ); final DrawableShape? circle = find(root, 'circle'); @@ -318,7 +345,10 @@ void main() { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse( svgStr, - theme: const SvgTheme(currentColor: currentColor), + theme: const SvgTheme( + currentColor: currentColor, + fontSize: 14.0, + ), ); final DrawableShape? circle = find(root, 'circle'); @@ -344,7 +374,10 @@ void main() { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse( svgStr, - theme: const SvgTheme(currentColor: Color(0xFFB0E3BE)), + theme: const SvgTheme( + currentColor: Color(0xFFB0E3BE), + fontSize: 14.0, + ), ); final DrawableShape? circle = find(root, 'circle'); @@ -372,7 +405,10 @@ void main() { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse( svgStr, - theme: const SvgTheme(currentColor: currentColor), + theme: const SvgTheme( + currentColor: currentColor, + fontSize: 14.0, + ), ); final DrawableShape? circle = find(root, 'circle'); @@ -400,7 +436,10 @@ void main() { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse( svgStr, - theme: const SvgTheme(currentColor: currentColor), + theme: const SvgTheme( + currentColor: currentColor, + fontSize: 14.0, + ), ); final DrawableShape? circle = find(root, 'circle'); @@ -426,7 +465,10 @@ void main() { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse( svgStr, - theme: const SvgTheme(currentColor: Color(0xFFB0E3BE)), + theme: const SvgTheme( + currentColor: Color(0xFFB0E3BE), + fontSize: 14.0, + ), ); final DrawableShape? circle = find(root, 'circle'); @@ -460,7 +502,10 @@ void main() { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse( svgStr, - theme: const SvgTheme(currentColor: currentColor), + theme: const SvgTheme( + currentColor: currentColor, + fontSize: 14.0, + ), ); final DrawableLinearGradient? gradient = @@ -498,7 +543,10 @@ void main() { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse( svgStr, - theme: const SvgTheme(currentColor: currentColor), + theme: const SvgTheme( + currentColor: currentColor, + fontSize: 14.0, + ), ); final DrawableLinearGradient? gradient = @@ -536,7 +584,10 @@ void main() { final SvgParser parser = SvgParser(); final DrawableRoot root = await parser.parse( svgStr, - theme: const SvgTheme(currentColor: Color(0xFFB0E3BE)), + theme: const SvgTheme( + currentColor: Color(0xFFB0E3BE), + fontSize: 14.0, + ), ); final DrawableLinearGradient? gradient = @@ -556,4 +607,177 @@ void main() { }); }); }); + + group('calculates em units based on the font size for', () { + test('svg (width, height)', () async { + const String svgStr = ''' + +'''; + + const double fontSize = 26.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + ), + ); + + expect(root.viewport.width, equals(fontSize * 5)); + expect(root.viewport.height, equals(fontSize * 6)); + }); + + test('use (x, y)', () async { + const String svgStr = ''' + + + + +'''; + + const double fontSize = 26.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + ), + ); + + final DrawableGroup? circle = find(root, 'anotherCircle'); + + const double expectedX = fontSize * 2; + const double expectedY = fontSize * 4; + + expect(circle, isNotNull); + expect( + circle!.transform, + equals( + (Matrix4.identity()..translate(expectedX, expectedY)).storage, + ), + ); + }); + + test('text (x, y)', () async { + const String svgStr = ''' + + Test + +'''; + + const double fontSize = 26.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + ), + ); + + final DrawableText? text = find(root, 'text'); + + const Offset expectedOffset = Offset(fontSize * 2, fontSize * 4); + + expect(text, isNotNull); + expect(text!.offset, equals(expectedOffset)); + }); + + test('radialGradient (cx, cy, r, fx, fy)', () async { + const String svgStr = ''' + + + + + + + + +'''; + + const double fontSize = 26.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + ), + ); + + final DrawableRadialGradient? gradient = + root.definitions.getGradient('url(#gradient)'); + + expect(gradient, isNotNull); + + const Offset expectedOffset = Offset(fontSize * 1, fontSize * 2); + const double expectedRadius = fontSize * 1.1; + const Offset expectedFocal = Offset(fontSize * 1.5, fontSize * 1.6); + + expect(gradient, isNotNull); + expect(gradient!.center, equals(expectedOffset)); + expect(gradient.radius, equals(expectedRadius)); + expect(gradient.focal, equals(expectedFocal)); + }); + + test('linearGradient (x1, y1, x2, y2)', () async { + const String svgStr = ''' + + + + + + + +'''; + + const double fontSize = 26.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + ), + ); + + final DrawableLinearGradient? gradient = + root.definitions.getGradient('url(#gradient)'); + + expect(gradient, isNotNull); + + const Offset expectedFromOffset = Offset(fontSize * 1, fontSize * 1.75); + const Offset expectedToOffset = Offset(fontSize * 1.5, fontSize * 1.6); + + expect(gradient, isNotNull); + expect(gradient!.from, equals(expectedFromOffset)); + expect(gradient.to, equals(expectedToOffset)); + }); + + test('image (x, y, width, height)', () async { + const String svgStr = ''' + + + +'''; + + const double fontSize = 26.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + ), + ); + + final DrawableRasterImage? image = + find(root, 'image'); + + const Offset expectedOffset = Offset(fontSize * 1, fontSize * 0.5); + const Size expectedSize = Size(fontSize * 2, fontSize * 1.5); + + expect(image, isNotNull); + expect(image!.offset, equals(expectedOffset)); + expect(image.size, equals(expectedSize)); + }); + }); } diff --git a/third_party/test/theme_test.dart b/third_party/test/theme_test.dart index af2d270f9bcd..998d45dd147d 100644 --- a/third_party/test/theme_test.dart +++ b/third_party/test/theme_test.dart @@ -11,20 +11,48 @@ void main() { const Color currentColor = Color(0xFFB0E3BE); expect( - SvgTheme(currentColor: currentColor).currentColor, + SvgTheme( + currentColor: currentColor, + fontSize: 14.0, + ).currentColor, equals(currentColor), ); }); + + test('sets fontSize', () { + const double fontSize = 14.0; + + expect( + SvgTheme( + currentColor: Color(0xFFB0E3BE), + fontSize: fontSize, + ).fontSize, + equals(fontSize), + ); + }); + + test( + 'sets fontSize to 14 ' + 'by default', () { + expect( + SvgTheme(), + equals( + SvgTheme(fontSize: 14.0), + ), + ); + }); }); test('supports value equality', () { expect( SvgTheme( currentColor: Color(0xFF6F2173), + fontSize: 14.0, ), equals( SvgTheme( currentColor: Color(0xFF6F2173), + fontSize: 14.0, ), ), ); diff --git a/third_party/test/vector_drawable_test.dart b/third_party/test/vector_drawable_test.dart index 4adfcc05d313..250ab0cf890b 100644 --- a/third_party/test/vector_drawable_test.dart +++ b/third_party/test/vector_drawable_test.dart @@ -35,7 +35,6 @@ void main() { false, const ColorFilter.mode(Color(0xFF00FF00), BlendMode.color), 'test', - theme: const SvgTheme(), ); final Image image = await info.picture!.toImage(2, 2); final ByteData data = (await image.toByteData())!; @@ -59,7 +58,6 @@ void main() { false, null, 'test', - theme: const SvgTheme(), ); expect(info.createLayer().isComplexHint, true); diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 198d7931f469..bb51e695b5af 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -597,10 +597,8 @@ void main() { testWidgets('Nested SVG elements report a FlutterError', (WidgetTester tester) async { await svg.fromSvgString( - '', - 'test', - theme: const SvgTheme(), - ); + '', + 'test'); final UnsupportedError error = tester.takeException() as UnsupportedError; expect(error.message, 'Unsupported nested element.'); }); @@ -752,6 +750,102 @@ void main() { expect(renderObject.clipBehavior, equals(Clip.antiAlias)); }); + group('SvgPicture respects em units', () { + testWidgets('circle (cx, cy, r)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme(fontSize: 600), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'circle.em.png'); + }); + + testWidgets('rect (x, y, width, height, rx, ry)', + (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme(fontSize: 100), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'rect.em.png'); + }); + + testWidgets('ellipse (cx, cy, rx, ry)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme(fontSize: 100), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'ellipse.em.png'); + }); + + testWidgets('line (x1, x2, y1, y2)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme(fontSize: 100), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'line.em.png'); + }); + }); + testWidgets('SvgPicture - two of the same', (WidgetTester tester) async { // Regression test to make sure the same SVG can render twice in the same // view. If layers are incorrectly reused, this will fail. diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index 46001688cdf5..f208960b86e3 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -3,6 +3,7 @@ import 'dart:ui'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/src/svg/xml_parsers.dart'; import 'package:flutter_svg/src/utilities/xml.dart'; +import 'package:path_drawing/path_drawing.dart'; import 'package:test/test.dart'; import 'package:xml/xml_events.dart'; @@ -80,35 +81,65 @@ void main() { parseEvents('').first as XmlStartElementEvent; expect( - parseViewBox(svgWithViewBoxAndWidthHeight.attributes.toAttributeMap())! + parseViewBox( + svgWithViewBoxAndWidthHeight.attributes.toAttributeMap(), + fontSize: 14.0, + )! .size, const Size(50, 50)); expect( - parseViewBox(svgWithViewBox.attributes.toAttributeMap())!.viewBoxRect, + parseViewBox( + svgWithViewBox.attributes.toAttributeMap(), + fontSize: 14.0, + )! + .viewBoxRect, rect); expect( - parseViewBox(svgWithViewBox.attributes.toAttributeMap())!.viewBoxOffset, + parseViewBox( + svgWithViewBox.attributes.toAttributeMap(), + fontSize: 14.0, + )! + .viewBoxOffset, Offset.zero); expect( - parseViewBox(svgWithViewBoxAndWidthHeight.attributes.toAttributeMap())! + parseViewBox( + svgWithViewBoxAndWidthHeight.attributes.toAttributeMap(), + fontSize: 14.0, + )! .viewBoxRect, rect); expect( - parseViewBox(svgWithWidthHeight.attributes.toAttributeMap())! + parseViewBox( + svgWithWidthHeight.attributes.toAttributeMap(), + fontSize: 14.0, + )! .viewBoxRect, rect); expect( - parseViewBox(svgWithNoSizeInfo.attributes.toAttributeMap(), - nullOk: true), + parseViewBox( + svgWithNoSizeInfo.attributes.toAttributeMap(), + fontSize: 14.0, + nullOk: true, + ), null); - expect(() => parseViewBox(svgWithNoSizeInfo.attributes.toAttributeMap()), + expect( + () => parseViewBox( + svgWithNoSizeInfo.attributes.toAttributeMap(), + fontSize: 14.0, + ), throwsStateError); expect( - parseViewBox(svgWithViewBoxMinXMinY.attributes.toAttributeMap())! + parseViewBox( + svgWithViewBoxMinXMinY.attributes.toAttributeMap(), + fontSize: 14.0, + )! .viewBoxRect, rect); expect( - parseViewBox(svgWithViewBoxMinXMinY.attributes.toAttributeMap())! + parseViewBox( + svgWithViewBoxMinXMinY.attributes.toAttributeMap(), + fontSize: 14.0, + )! .viewBoxOffset, const Offset(-42.0, -56.0)); }); @@ -147,9 +178,21 @@ void main() { parseEvents('').first as XmlStartElementEvent; - // TODO(dnfield): DashOffset is completely opaque right now, maybe expose the raw value? - expect(parseDashOffset(abs.attributes.toAttributeMap()), isNotNull); - expect(parseDashOffset(pct.attributes.toAttributeMap()), isNotNull); + expect( + parseDashOffset( + abs.attributes.toAttributeMap(), + fontSize: 14.0, + ), + equals(const DashOffset.absolute(20.0)), + ); + + expect( + parseDashOffset( + pct.attributes.toAttributeMap(), + fontSize: 14.0, + ), + equals(DashOffset.percentage(0.2)), + ); }); test('font-weight tests', () { @@ -213,9 +256,13 @@ void main() { null, null, currentColor: currentColor, + fontSize: 14.0, ); - expect(svgStyle.stroke?.color, equals(currentColor)); + expect( + svgStyle.stroke?.color, + equals(currentColor), + ); }); test('uses currentColor for fill color', () { @@ -231,9 +278,93 @@ void main() { null, null, currentColor: currentColor, + fontSize: 14.0, + ); + + expect( + svgStyle.fill?.color, + equals(currentColor), + ); + }); + + test( + 'calculates em units based on the font size ' + 'for stroke width', () { + final XmlStartElementEvent svg = + parseEvents('').first + as XmlStartElementEvent; + + const double fontSize = 26.0; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + fontSize: fontSize, ); - expect(svgStyle.fill?.color, equals(currentColor)); + expect( + svgStyle.stroke?.strokeWidth, + equals(fontSize * 2), + ); + }); + + test( + 'calculates em units based on the font size ' + 'for dash array', () { + final XmlStartElementEvent svg = parseEvents( + '', + ).first as XmlStartElementEvent; + + const double fontSize = 26.0; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + fontSize: fontSize, + ); + + expect( + [ + svgStyle.dashArray!.next, + svgStyle.dashArray!.next, + svgStyle.dashArray!.next, + ], + equals([ + fontSize * 0.2, + fontSize * 0.5, + 10, + ]), + ); + }); + + test( + 'calculates em units based on the font size ' + 'for dash offset', () { + final XmlStartElementEvent svg = parseEvents( + '', + ).first as XmlStartElementEvent; + + const double fontSize = 26.0; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + fontSize: fontSize, + ); + + expect( + svgStyle.dashOffset, + equals(const DashOffset.absolute(fontSize * 0.15)), + ); }); }); } diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart index afb04a1d99f9..80f4faff5555 100644 --- a/third_party/tool/gen_golden.dart +++ b/third_party/tool/gen_golden.dart @@ -19,8 +19,11 @@ Future getSvgImage(String svgData) async { const Size size = Size(200.0, 200.0); - final DrawableRoot svgRoot = - await svg.fromSvgString(svgData, 'GenGoldenTest'); + final DrawableRoot svgRoot = await svg.fromSvgString( + svgData, + 'GenGoldenTest', + ); + svgRoot.scaleCanvasToViewBox(canvas, size); svgRoot.clipCanvasToViewBox(canvas); From 77513856cc629bc3f051e332423a969227a305e7 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 29 Nov 2021 16:47:37 -0800 Subject: [PATCH 415/512] Update picture_provider.dart --- third_party/lib/src/picture_provider.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index e39511916ee2..d6edfa701909 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -333,7 +333,6 @@ abstract class PictureProvider { final ColorFilter? colorFilter; /// The default theme used when parsing SVG elements. - @visibleForTesting SvgTheme get theme => _theme; SvgTheme _theme; From 559face505686568543d59bbfd6f7a50dcf4dab9 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 29 Nov 2021 23:07:35 -0800 Subject: [PATCH 416/512] Update picture_provider.dart --- third_party/lib/src/picture_provider.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index d6edfa701909..00d732b1eefd 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -314,7 +314,6 @@ abstract class PictureProvider { final PictureInfoDecoderBuilder decoderBuilder; /// The [PictureInfoDecoder] to use for loading this picture. - @visibleForTesting PictureInfoDecoder decoder; /// The [PictureCache] for [Picture] objects created by [PictureProvider] From a8ba7fecd10cf0ea3c31939660cd2a9e6fa9c3a1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 30 Nov 2021 11:29:13 -0800 Subject: [PATCH 417/512] Update xml_parsers.dart --- third_party/lib/src/svg/xml_parsers.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index de53a91f89e3..7126866fdfad 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -32,7 +32,8 @@ double _parseRawWidthHeight( } return true; }()); - return parseDoubleWithUnits(raw, fontSize: fontSize) ?? double.infinity; + return parseDoubleWithUnits(raw, fontSize: fontSize, tryParse: true) ?? + double.infinity; } /// Parses an SVG @viewBox attribute (e.g. 0 0 100 100) to a [Rect]. From e91e5915a589eac33d25951345309f32d7a0cce0 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 2 Dec 2021 10:37:30 -0800 Subject: [PATCH 418/512] Version bump information --- third_party/CHANGELOG.md | 2 ++ third_party/lib/src/svg/xml_parsers.dart | 2 +- third_party/pubspec.yaml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 75dcdadd9b2b..69d1cbf228f3 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -6,6 +6,8 @@ near or overlapping an animating widget. Also should improve raster cacheability. - Correctly list web as a supported platform. +- Support for em/ex units. +- Stable 1.0.0 release. ## 0.23.0+1 diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 7126866fdfad..fd4872a857dc 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -32,7 +32,7 @@ double _parseRawWidthHeight( } return true; }()); - return parseDoubleWithUnits(raw, fontSize: fontSize, tryParse: true) ?? + return parseDoubleWithUnits(raw, fontSize: fontSize, tryParse: true) ?? double.infinity; } diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index a1819e04c986..7007f00f8bde 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -7,7 +7,7 @@ dependencies: flutter: sdk: flutter meta: ^1.3.0 - path_drawing: ^0.5.1+1 + path_drawing: ^1.0.0 vector_math: ^2.1.0 xml: ^5.0.0 From 371db5bd760a4e5b2ff7bac84e6938863cd1f8e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=C3=A0o=20Ho=C3=A0ng=20S=C6=A1n?= Date: Fri, 3 Dec 2021 22:37:21 +0700 Subject: [PATCH 419/512] Requires Flutter >=2.4.0 for LayerHandle usage. (#611) See https://github.com/flutter/flutter/commit/025397ae3f925b316991912977367d3263cc4432 --- third_party/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 7007f00f8bde..7ca0bf796273 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -21,7 +21,7 @@ dev_dependencies: environment: sdk: '>=2.12.0 <3.0.0' - flutter: ">=1.24.0-6.0.pre" + flutter: ">=2.4.0-0.0.pre" ## For developing features that require new functionality in engine: # dependency_overrides: From a5c9a2b6a48e44efb776ffd8d549b223f4f6ba3c Mon Sep 17 00:00:00 2001 From: Bartosz Selwesiuk Date: Wed, 8 Dec 2021 18:31:31 +0100 Subject: [PATCH 420/512] Add support for ex units (#618) * feat: add xHeight to SvgTheme * test: add SvgTheme xHeight tests * feat: use xHeight when updating PictureProvider in SvgPicture * test: add xHeight to DefaultSvgTheme and PictureProvider tests * feat: add support for parsing ex units * test: fix existing tests after introducing xHeight * test: add DefaultSvgTheme xHeight tests * test: add parseStyle xHeight tests (stroke width, dash array, dash offset) * test: add SvgParser xHeight tests (svg, use, text, radialGradient, linearGradient, image) * test: add SvgPicture xHeight tests for shapes (circle, rect, ellipse, line) * test: PictureProvider rebuilds a decoder when the theme changes * test: fix relative font size tests * test: add ex font size tests * test: fix DefaultSvgTheme tests * revert: SvgTheme equals operator should use runtimeType --- third_party/lib/src/svg/parser_state.dart | 105 ++++-- third_party/lib/src/svg/parsers.dart | 5 +- third_party/lib/src/svg/theme.dart | 14 +- third_party/lib/src/svg/xml_parsers.dart | 32 +- third_party/lib/src/utilities/numbers.dart | 19 +- third_party/lib/svg.dart | 6 + third_party/test/default_theme_test.dart | 55 ++++ .../{circle.em.png => circle.em_ex.png} | Bin .../{ellipse.em.png => ellipse.em_ex.png} | Bin .../{line.em.png => line.em_ex.png} | Bin .../{rect.em.png => rect.em_ex.png} | Bin third_party/test/picture_cache_test.dart | 1 + third_party/test/picture_provider_test.dart | 127 ++------ third_party/test/svg_parsers_test.dart | 305 ++++++++++++++++-- third_party/test/theme_test.dart | 27 ++ third_party/test/widget_svg_test.dart | 118 ++++++- third_party/test/xml_svg_test.dart | 246 +++++++++----- 17 files changed, 812 insertions(+), 248 deletions(-) rename third_party/test/golden_widget/{circle.em.png => circle.em_ex.png} (100%) rename third_party/test/golden_widget/{ellipse.em.png => ellipse.em_ex.png} (100%) rename third_party/test/golden_widget/{line.em.png => line.em_ex.png} (100%) rename third_party/test/golden_widget/{rect.em.png => rect.em_ex.png} (100%) diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index c1952765933e..d805df1ec875 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -20,7 +20,7 @@ final Set _unhandledElements = {'title', 'desc'}; typedef _ParseFunc = Future? Function( SvgParserState parserState, bool warningsAsErrors); typedef _PathFunc = Path? Function( - Map attributes, double fontSize); + Map attributes, double fontSize, double xHeight); final RegExp _trimPattern = RegExp(r'[\r|\n|\t]'); @@ -52,20 +52,31 @@ Offset _parseCurrentOffset(SvgParserState parserState, Offset? lastOffset) { final String? x = parserState.attribute('x', def: null); final String? y = parserState.attribute('y', def: null); final double fontSize = parserState.fontSize; + final double xHeight = parserState.xHeight; return Offset( x != null - ? parseDoubleWithUnits(x, fontSize: fontSize)! + ? parseDoubleWithUnits( + x, + fontSize: fontSize, + xHeight: xHeight, + )! : parseDoubleWithUnits( parserState.attribute('dx', def: '0'), fontSize: fontSize, + xHeight: xHeight, )! + (lastOffset?.dx ?? 0), y != null - ? parseDoubleWithUnits(y, fontSize: fontSize)! + ? parseDoubleWithUnits( + y, + fontSize: fontSize, + xHeight: xHeight, + )! : parseDoubleWithUnits( parserState.attribute('dy', def: '0'), fontSize: fontSize, + xHeight: xHeight, )! + (lastOffset?.dy ?? 0), ); @@ -92,6 +103,7 @@ class _Elements { final DrawableViewport? viewBox = parseViewBox( parserState.attributes, fontSize: parserState.fontSize, + xHeight: parserState.xHeight, ); final String? id = parserState.attribute('id', def: ''); @@ -136,6 +148,7 @@ class _Elements { null, currentColor: color, fontSize: parserState.fontSize, + xHeight: parserState.xHeight, ), color: color, ), @@ -156,6 +169,7 @@ class _Elements { null, currentColor: color, fontSize: parserState.fontSize, + xHeight: parserState.xHeight, ), color: color, ); @@ -179,6 +193,7 @@ class _Elements { parent.style, currentColor: color, fontSize: parserState.fontSize, + xHeight: parserState.xHeight, ), transform: parseTransform(parserState.attribute('transform'))?.storage, color: color, @@ -207,6 +222,7 @@ class _Elements { parent.style, currentColor: color, fontSize: parserState.fontSize, + xHeight: parserState.xHeight, ), transform: parseTransform(parserState.attribute('transform'))?.storage, color: color, @@ -230,6 +246,7 @@ class _Elements { parent!.style, currentColor: parent.color, fontSize: parserState.fontSize, + xHeight: parserState.xHeight, ); final Matrix4 transform = @@ -239,10 +256,12 @@ class _Elements { parseDoubleWithUnits( parserState.attribute('x', def: '0'), fontSize: parserState.fontSize, + xHeight: parserState.xHeight, ), parseDoubleWithUnits( parserState.attribute('y', def: '0'), fontSize: parserState.fontSize, + xHeight: parserState.xHeight, )!, ); @@ -301,6 +320,7 @@ class _Elements { bool warningsAsErrors, ) { final double fontSize = parserState.fontSize; + final double xHeight = parserState.xHeight; final String? gradientUnits = getAttribute( parserState.attributes, 'gradientUnits', @@ -351,24 +371,24 @@ class _Elements { cx = isPercentage(rawCx!) ? parsePercentage(rawCx) * parserState.rootBounds.width + parserState.rootBounds.left - : parseDoubleWithUnits(rawCx, fontSize: fontSize)!; + : parseDoubleWithUnits(rawCx, fontSize: fontSize, xHeight: xHeight)!; cy = isPercentage(rawCy!) ? parsePercentage(rawCy) * parserState.rootBounds.height + parserState.rootBounds.top - : parseDoubleWithUnits(rawCy, fontSize: fontSize)!; + : parseDoubleWithUnits(rawCy, fontSize: fontSize, xHeight: xHeight)!; r = isPercentage(rawR!) ? parsePercentage(rawR) * ((parserState.rootBounds.height + parserState.rootBounds.width) / 2) - : parseDoubleWithUnits(rawR, fontSize: fontSize)!; + : parseDoubleWithUnits(rawR, fontSize: fontSize, xHeight: xHeight)!; fx = isPercentage(rawFx!) ? parsePercentage(rawFx) * parserState.rootBounds.width + parserState.rootBounds.left - : parseDoubleWithUnits(rawFx, fontSize: fontSize)!; + : parseDoubleWithUnits(rawFx, fontSize: fontSize, xHeight: xHeight)!; fy = isPercentage(rawFy!) ? parsePercentage(rawFy) * parserState.rootBounds.height + parserState.rootBounds.top - : parseDoubleWithUnits(rawFy, fontSize: fontSize)!; + : parseDoubleWithUnits(rawFy, fontSize: fontSize, xHeight: xHeight)!; } parserState._definitions.addGradient( @@ -393,6 +413,7 @@ class _Elements { static Future? linearGradient( SvgParserState parserState, bool warningsAsErrors) { final double fontSize = parserState.fontSize; + final double xHeight = parserState.xHeight; final String? gradientUnits = getAttribute( parserState.attributes, 'gradientUnits', @@ -445,22 +466,22 @@ class _Elements { isPercentage(x1!) ? parsePercentage(x1) * parserState.rootBounds.width + parserState.rootBounds.left - : parseDoubleWithUnits(x1, fontSize: fontSize)!, + : parseDoubleWithUnits(x1, fontSize: fontSize, xHeight: xHeight)!, isPercentage(y1!) ? parsePercentage(y1) * parserState.rootBounds.height + parserState.rootBounds.top - : parseDoubleWithUnits(y1, fontSize: fontSize)!, + : parseDoubleWithUnits(y1, fontSize: fontSize, xHeight: xHeight)!, ); toOffset = Offset( isPercentage(x2!) ? parsePercentage(x2) * parserState.rootBounds.width + parserState.rootBounds.left - : parseDoubleWithUnits(x2, fontSize: fontSize)!, + : parseDoubleWithUnits(x2, fontSize: fontSize, xHeight: xHeight)!, isPercentage(y2!) ? parsePercentage(y2) * parserState.rootBounds.height + parserState.rootBounds.top - : parseDoubleWithUnits(y2, fontSize: fontSize)!, + : parseDoubleWithUnits(y2, fontSize: fontSize, xHeight: xHeight)!, ); } @@ -497,7 +518,11 @@ class _Elements { if (pathFn != null) { final Path nextPath = applyTransformIfNeeded( - pathFn(parserState.attributes, parserState.fontSize), + pathFn( + parserState.attributes, + parserState.fontSize, + parserState.xHeight, + ), parserState.attributes, )!; nextPath.fillType = @@ -556,6 +581,7 @@ class _Elements { static Future image( SvgParserState parserState, bool warningsAsErrors) async { final double fontSize = parserState.fontSize; + final double xHeight = parserState.xHeight; final String? href = getHrefAttribute(parserState.attributes); if (href == null) { return; @@ -564,20 +590,24 @@ class _Elements { parseDoubleWithUnits( parserState.attribute('x', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!, parseDoubleWithUnits( parserState.attribute('y', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!, ); final Size size = Size( parseDoubleWithUnits( parserState.attribute('width', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!, parseDoubleWithUnits( parserState.attribute('height', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!, ); final Image image = await resolveImage(href); @@ -595,6 +625,7 @@ class _Elements { parentStyle, currentColor: parent.color, fontSize: parserState.fontSize, + xHeight: parserState.xHeight, ), size: size, transform: parseTransform(parserState.attribute('transform'))?.storage, @@ -681,6 +712,7 @@ class _Elements { parserState.rootBounds, parentStyle, fontSize: parserState.fontSize, + xHeight: parserState.xHeight, ), currentOffset, transform, @@ -715,44 +747,57 @@ class _Elements { // ignore: avoid_classes_with_only_static_members class _Paths { - static Path circle(Map attributes, double fontSize) { + static Path circle( + Map attributes, + double fontSize, + double xHeight, + ) { final double cx = parseDoubleWithUnits( getAttribute(attributes, 'cx', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double cy = parseDoubleWithUnits( getAttribute(attributes, 'cy', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double r = parseDoubleWithUnits( getAttribute(attributes, 'r', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final Rect oval = Rect.fromCircle(center: Offset(cx, cy), radius: r); return Path()..addOval(oval); } - static Path path(Map attributes, double fontSize) { + static Path path( + Map attributes, double fontSize, double xHeight) { final String d = getAttribute(attributes, 'd')!; return parseSvgPathData(d); } - static Path rect(Map attributes, double fontSize) { + static Path rect( + Map attributes, double fontSize, double xHeight) { final double x = parseDoubleWithUnits( getAttribute(attributes, 'x', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double y = parseDoubleWithUnits( getAttribute(attributes, 'y', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double w = parseDoubleWithUnits( getAttribute(attributes, 'width', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double h = parseDoubleWithUnits( getAttribute(attributes, 'height', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final Rect rect = Rect.fromLTWH(x, y, w, h); String? rxRaw = getAttribute(attributes, 'rx', def: null); @@ -764,10 +809,12 @@ class _Paths { final double rx = parseDoubleWithUnits( rxRaw, fontSize: fontSize, + xHeight: xHeight, )!; final double ry = parseDoubleWithUnits( ryRaw, fontSize: fontSize, + xHeight: xHeight, )!; return Path()..addRRect(RRect.fromRectXY(rect, rx, ry)); @@ -776,11 +823,13 @@ class _Paths { return Path()..addRect(rect); } - static Path? polygon(Map attributes, double fontSize) { + static Path? polygon( + Map attributes, double fontSize, double xHeight) { return parsePathFromPoints(attributes, true); } - static Path? polyline(Map attributes, double fontSize) { + static Path? polyline( + Map attributes, double fontSize, double xHeight) { return parsePathFromPoints(attributes, false); } @@ -794,44 +843,54 @@ class _Paths { return parseSvgPathData(path); } - static Path ellipse(Map attributes, double fontSize) { + static Path ellipse( + Map attributes, double fontSize, double xHeight) { final double cx = parseDoubleWithUnits( getAttribute(attributes, 'cx', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double cy = parseDoubleWithUnits( getAttribute(attributes, 'cy', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double rx = parseDoubleWithUnits( getAttribute(attributes, 'rx', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double ry = parseDoubleWithUnits( getAttribute(attributes, 'ry', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final Rect r = Rect.fromLTWH(cx - rx, cy - ry, rx * 2, ry * 2); return Path()..addOval(r); } - static Path line(Map attributes, double fontSize) { + static Path line( + Map attributes, double fontSize, double xHeight) { final double x1 = parseDoubleWithUnits( getAttribute(attributes, 'x1', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double x2 = parseDoubleWithUnits( getAttribute(attributes, 'x2', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double y1 = parseDoubleWithUnits( getAttribute(attributes, 'y1', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; final double y2 = parseDoubleWithUnits( getAttribute(attributes, 'y2', def: '0'), fontSize: fontSize, + xHeight: xHeight, )!; return Path() @@ -1011,7 +1070,7 @@ class SvgParserState { final DrawableParent parent = _parentDrawables.last.drawable!; final DrawableStyle? parentStyle = parent.style; - final Path path = pathFunc(attributes, fontSize)!; + final Path path = pathFunc(attributes, fontSize, xHeight)!; final DrawableStyleable drawable = DrawableShape( getAttribute(attributes, 'id', def: ''), path, @@ -1024,6 +1083,7 @@ class SvgParserState { defaultFillColor: colorBlack, currentColor: parent.color, fontSize: fontSize, + xHeight: xHeight, ), transform: parseTransform(getAttribute(attributes, 'transform'))?.storage, ); @@ -1092,4 +1152,7 @@ class SvgParserState { extension on SvgParserState { /// Retrieves the font size of the current [theme]. double get fontSize => theme.fontSize; + + /// Retrieves the x-height of the current [theme]. + double get xHeight => theme.xHeight; } diff --git a/third_party/lib/src/svg/parsers.dart b/third_party/lib/src/svg/parsers.dart index 36e89e87ac0c..14d226d9b2c1 100644 --- a/third_party/lib/src/svg/parsers.dart +++ b/third_party/lib/src/svg/parsers.dart @@ -21,10 +21,12 @@ final Map _kTextSizeMap = { /// Parses a `font-size` attribute. /// -/// Uses [fontSize] to calculate the font size including em units. +/// Uses [fontSize] and [xHeight] to calculate the font size +/// that includes em or ex units. double? parseFontSize( String? raw, { required double fontSize, + required double xHeight, double? parentValue, }) { if (raw == null || raw == '') { @@ -35,6 +37,7 @@ double? parseFontSize( raw, tryParse: true, fontSize: fontSize, + xHeight: xHeight, ); if (ret != null) { return ret; diff --git a/third_party/lib/src/svg/theme.dart b/third_party/lib/src/svg/theme.dart index 1cde53d9a864..9ab6dbdd385f 100644 --- a/third_party/lib/src/svg/theme.dart +++ b/third_party/lib/src/svg/theme.dart @@ -12,7 +12,8 @@ class SvgTheme { const SvgTheme({ this.currentColor, this.fontSize = 14, - }); + double? xHeight, + }) : xHeight = xHeight ?? fontSize / 2; /// The default color applied to SVG elements that inherit the color property. /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword @@ -22,16 +23,23 @@ class SvgTheme { /// See: https://www.w3.org/TR/SVG11/coords.html#Units final double fontSize; + /// The x-height (corpus size) of the font used when calculating ex units of SVG elements. + /// Defaults to [fontSize] / 2 if not provided. + /// See: https://www.w3.org/TR/SVG11/coords.html#Units, https://en.wikipedia.org/wiki/X-height + final double xHeight; + @override bool operator ==(dynamic other) { if (other.runtimeType != runtimeType) { return false; } + return other is SvgTheme && currentColor == other.currentColor && - fontSize == other.fontSize; + fontSize == other.fontSize && + xHeight == other.xHeight; } @override - int get hashCode => hashValues(currentColor, fontSize); + int get hashCode => hashValues(currentColor, fontSize, xHeight); } diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index fd4872a857dc..68fc881e78ba 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -13,6 +13,7 @@ import 'parsers.dart'; double _parseRawWidthHeight( String? raw, { required double fontSize, + required double xHeight, }) { if (raw == '100%' || raw == '') { return double.infinity; @@ -21,18 +22,21 @@ double _parseRawWidthHeight( final RegExp notDigits = RegExp(r'[^\d\.]'); if (!raw!.endsWith('px') && !raw.endsWith('em') && + !raw.endsWith('ex') && raw.contains(notDigits)) { print( 'Warning: Flutter SVG only supports the following formats for `width` and `height` on the SVG root:\n' ' width="100%"\n' ' width="100em"\n' + ' width="100ex"\n' ' width="100px"\n' ' width="100" (where the number will be treated as pixels).\n' 'The supplied value ($raw) will be discarded and treated as if it had not been specified.'); } return true; }()); - return parseDoubleWithUnits(raw, fontSize: fontSize, tryParse: true) ?? + return parseDoubleWithUnits(raw, + fontSize: fontSize, xHeight: xHeight, tryParse: true) ?? double.infinity; } @@ -46,6 +50,7 @@ double _parseRawWidthHeight( DrawableViewport? parseViewBox( Map svg, { required double fontSize, + required double xHeight, bool nullOk = false, }) { final String? viewBox = getAttribute(svg, 'viewBox'); @@ -64,15 +69,11 @@ DrawableViewport? parseViewBox( ' $svg'); } - final double width = _parseRawWidthHeight( - rawWidth, - fontSize: fontSize, - ); + final double width = + _parseRawWidthHeight(rawWidth, fontSize: fontSize, xHeight: xHeight); - final double height = _parseRawWidthHeight( - rawHeight, - fontSize: fontSize, - ); + final double height = + _parseRawWidthHeight(rawHeight, fontSize: fontSize, xHeight: xHeight); if (viewBox == '') { return DrawableViewport( @@ -128,6 +129,7 @@ TileMode parseTileMode(Map attributes) { CircularIntervalList? parseDashArray( Map attributes, { required double fontSize, + required double xHeight, }) { final String? rawDashArray = getAttribute(attributes, 'stroke-dasharray'); if (rawDashArray == '') { @@ -138,7 +140,8 @@ CircularIntervalList? parseDashArray( final List parts = rawDashArray!.split(RegExp(r'[ ,]+')); return CircularIntervalList(parts - .map((String part) => parseDoubleWithUnits(part, fontSize: fontSize)!) + .map((String part) => + parseDoubleWithUnits(part, fontSize: fontSize, xHeight: xHeight)!) .toList()); } @@ -146,6 +149,7 @@ CircularIntervalList? parseDashArray( DashOffset? parseDashOffset( Map attributes, { required double fontSize, + required double xHeight, }) { final String? rawDashOffset = getAttribute(attributes, 'stroke-dashoffset'); if (rawDashOffset == '') { @@ -158,6 +162,7 @@ DashOffset? parseDashOffset( return DashOffset.absolute(parseDoubleWithUnits( rawDashOffset, fontSize: fontSize, + xHeight: xHeight, )!); } } @@ -200,6 +205,7 @@ DrawablePaint? parseStroke( DrawablePaint? parentStroke, Color? currentColor, double fontSize, + double xHeight, ) { final String rawStroke = getAttribute(attributes, 'stroke')!; final String? rawStrokeOpacity = getAttribute( @@ -264,6 +270,7 @@ DrawablePaint? parseStroke( : parseDoubleWithUnits( rawStrokeWidth, fontSize: fontSize, + xHeight: xHeight, ), ); return paint; @@ -499,6 +506,7 @@ DrawableStyle parseStyle( Rect? bounds, DrawableStyle? parentStyle, { required double fontSize, + required double xHeight, Color? defaultFillColor, Color? currentColor, }) { @@ -512,14 +520,17 @@ DrawableStyle parseStyle( parentStyle?.stroke, currentColor, fontSize, + xHeight, ), dashArray: parseDashArray( attributes, fontSize: fontSize, + xHeight: xHeight, ), dashOffset: parseDashOffset( attributes, fontSize: fontSize, + xHeight: xHeight, ), fill: parseFill( key, @@ -544,6 +555,7 @@ DrawableStyle parseStyle( getAttribute(attributes, 'font-size'), parentValue: parentStyle?.textStyle?.fontSize, fontSize: fontSize, + xHeight: xHeight, ), fontWeight: parseFontWeight( getAttribute(attributes, 'font-weight', def: null), diff --git a/third_party/lib/src/utilities/numbers.dart b/third_party/lib/src/utilities/numbers.dart index 1b3f2f1ac26c..9d88071a449a 100644 --- a/third_party/lib/src/utilities/numbers.dart +++ b/third_party/lib/src/utilities/numbers.dart @@ -1,6 +1,6 @@ /// Parses a [rawDouble] `String` to a `double`. /// -/// The [rawDouble] might include a unit (`px` or `em`) +/// The [rawDouble] might include a unit (`px`, `em` or `ex`) /// which is stripped off when parsed to a `double`. /// /// Passing `null` will return `null`. @@ -10,7 +10,11 @@ double? parseDouble(String? rawDouble, {bool tryParse = false}) { return null; } - rawDouble = rawDouble.replaceFirst('em', '').replaceFirst('px', '').trim(); + rawDouble = rawDouble + .replaceFirst('em', '') + .replaceFirst('ex', '') + .replaceFirst('px', '') + .trim(); if (tryParse) { return double.tryParse(rawDouble); @@ -20,12 +24,16 @@ double? parseDouble(String? rawDouble, {bool tryParse = false}) { /// Parses a [rawDouble] `String` to a `double` /// taking into account absolute and relative units -/// (`px` or `em`). +/// (`px`, `em` or `ex`). /// /// Passing an `em` value will calculate the result /// relative to the provided [fontSize]: /// 1 em = 1 * [fontSize]. /// +/// Passing an `ex` value will calculate the result +/// relative to the provided [xHeight]: +/// 1 ex = 1 * [xHeight]. +/// /// The [rawDouble] might include a unit which is /// stripped off when parsed to a `double`. /// @@ -33,6 +41,7 @@ double? parseDouble(String? rawDouble, {bool tryParse = false}) { double? parseDoubleWithUnits( String? rawDouble, { required double fontSize, + required double xHeight, bool tryParse = false, }) { double unit = 1.0; @@ -41,6 +50,10 @@ double? parseDoubleWithUnits( if (rawDouble?.contains('em') ?? false) { unit = fontSize; } + // 1 ex unit is equal to the current x-height. + else if (rawDouble?.contains('ex') ?? false) { + unit = xHeight; + } final double? value = parseDouble( rawDouble, diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index b02018242977..0863dc36a549 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -787,9 +787,15 @@ class _SvgPictureState extends State { // See: https://api.flutter.dev/flutter/painting/TextStyle/fontSize.html 14.0; + final double xHeight = widget.theme?.xHeight ?? + defaultSvgTheme?.xHeight ?? + // Fallback to the font size divided by 2. + fontSize / 2; + widget.pictureProvider.theme = SvgTheme( currentColor: currentColor, fontSize: fontSize, + xHeight: xHeight, ); } diff --git a/third_party/test/default_theme_test.dart b/third_party/test/default_theme_test.dart index 2ee9dc9877dd..fd0074f6a9fb 100644 --- a/third_party/test/default_theme_test.dart +++ b/third_party/test/default_theme_test.dart @@ -12,6 +12,7 @@ void main() { const SvgTheme svgTheme = SvgTheme( currentColor: Color(0xFF733821), fontSize: 14.0, + xHeight: 6.0, ); final SvgPicture svgPictureWidget = SvgPicture.string(''' @@ -34,6 +35,7 @@ void main() { const SvgTheme anotherSvgTheme = SvgTheme( currentColor: Color(0xFF05290E), fontSize: 12.0, + xHeight: 7.0, ); await tester.pumpWidget(DefaultSvgTheme( @@ -157,5 +159,58 @@ void main() { equals(14.0), ); }); + + testWidgets( + 'xHeight from the widget\'s theme takes precedence over ' + 'the theme from DefaultSvgTheme', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + fontSize: 14.0, + xHeight: 6.5, + ); + + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + theme: SvgTheme( + fontSize: 12.0, + xHeight: 7.0, + ), + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + svgPicture.pictureProvider.theme.xHeight, + equals(7.0), + ); + }); + + testWidgets( + 'xHeight defaults to the font size divided by 2 (7.0) ' + 'if no widget\'s theme or DefaultSvgTheme is provided', + (WidgetTester tester) async { + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + ); + + await tester.pumpWidget(svgPictureWidget); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + svgPicture.pictureProvider.theme.xHeight, + equals(7.0), + ); + }); }); } diff --git a/third_party/test/golden_widget/circle.em.png b/third_party/test/golden_widget/circle.em_ex.png similarity index 100% rename from third_party/test/golden_widget/circle.em.png rename to third_party/test/golden_widget/circle.em_ex.png diff --git a/third_party/test/golden_widget/ellipse.em.png b/third_party/test/golden_widget/ellipse.em_ex.png similarity index 100% rename from third_party/test/golden_widget/ellipse.em.png rename to third_party/test/golden_widget/ellipse.em_ex.png diff --git a/third_party/test/golden_widget/line.em.png b/third_party/test/golden_widget/line.em_ex.png similarity index 100% rename from third_party/test/golden_widget/line.em.png rename to third_party/test/golden_widget/line.em_ex.png diff --git a/third_party/test/golden_widget/rect.em.png b/third_party/test/golden_widget/rect.em_ex.png similarity index 100% rename from third_party/test/golden_widget/rect.em.png rename to third_party/test/golden_widget/rect.em_ex.png diff --git a/third_party/test/picture_cache_test.dart b/third_party/test/picture_cache_test.dart index b0358fd58b84..cb8fd5da094b 100644 --- a/third_party/test/picture_cache_test.dart +++ b/third_party/test/picture_cache_test.dart @@ -80,6 +80,7 @@ void main() { svgString, )..theme = const SvgTheme( fontSize: 14.0, + xHeight: 7.0, ); await precachePicture( diff --git a/third_party/test/picture_provider_test.dart b/third_party/test/picture_provider_test.dart index b72ac51fe274..7b78caef0963 100644 --- a/third_party/test/picture_provider_test.dart +++ b/third_party/test/picture_provider_test.dart @@ -25,7 +25,7 @@ void main() { group( 'rebuilds the decoder using decoderBuilder ' - 'when currentColor changes', () { + 'when the theme changes', () { test('NetworkPicture', () async { const Color color = Color(0xFFB0E3BE); final NetworkPicture networkPicture = @@ -34,15 +34,17 @@ void main() { final PictureInfoDecoder? decoder = networkPicture.decoder; - // Update the theme of PictureProvider to include currentColor. - networkPicture.theme = SvgTheme( + const SvgTheme newTheme = SvgTheme( currentColor: color, fontSize: 14.0, + xHeight: 6.5, ); + networkPicture.theme = newTheme; + expect(networkPicture.decoder, isNotNull); expect(networkPicture.decoder, isNot(equals(decoder))); - expect(currentTheme?.currentColor, equals(color)); + expect(currentTheme, equals(newTheme)); }); test('FilePicture', () async { @@ -52,15 +54,17 @@ void main() { final PictureInfoDecoder? decoder = filePicture.decoder; - // Update the theme of PictureProvider to include currentColor. - filePicture.theme = SvgTheme( + const SvgTheme newTheme = SvgTheme( currentColor: color, fontSize: 14.0, + xHeight: 6.5, ); + filePicture.theme = newTheme; + expect(filePicture.decoder, isNotNull); expect(filePicture.decoder, isNot(equals(decoder))); - expect(currentTheme?.currentColor, equals(color)); + expect(currentTheme, equals(newTheme)); }); test('MemoryPicture', () async { @@ -71,15 +75,17 @@ void main() { final PictureInfoDecoder? decoder = memoryPicture.decoder; - // Update the theme of PictureProvider to include currentColor. - memoryPicture.theme = SvgTheme( + const SvgTheme newTheme = SvgTheme( currentColor: color, fontSize: 14.0, + xHeight: 6.5, ); + memoryPicture.theme = newTheme; + expect(memoryPicture.decoder, isNotNull); expect(memoryPicture.decoder, isNot(equals(decoder))); - expect(currentTheme?.currentColor, equals(color)); + expect(currentTheme, equals(newTheme)); }); test('StringPicture', () async { @@ -89,15 +95,17 @@ void main() { final PictureInfoDecoder? decoder = stringPicture.decoder; - // Update the theme of PictureProvider to include currentColor. - stringPicture.theme = SvgTheme( + const SvgTheme newTheme = SvgTheme( currentColor: color, fontSize: 14.0, + xHeight: 6.5, ); + stringPicture.theme = newTheme; + expect(stringPicture.decoder, isNotNull); expect(stringPicture.decoder, isNot(equals(decoder))); - expect(currentTheme?.currentColor, equals(color)); + expect(currentTheme, equals(newTheme)); }); test('ExactAssetPicture', () async { @@ -108,102 +116,17 @@ void main() { final PictureInfoDecoder? decoder = exactAssetPicture.decoder; - // Update the theme of PictureProvider to include currentColor. - exactAssetPicture.theme = SvgTheme( + const SvgTheme newTheme = SvgTheme( currentColor: color, fontSize: 14.0, + xHeight: 6.5, ); - expect(exactAssetPicture.decoder, isNotNull); - expect(exactAssetPicture.decoder, isNot(equals(decoder))); - expect(currentTheme?.currentColor, equals(color)); - }); - }); - - group( - 'rebuilds the decoder using decoderBuilder ' - 'when fontSize changes', () { - test('NetworkPicture', () async { - const double fontSize = 26.0; - final NetworkPicture networkPicture = - NetworkPicture(decoderBuilder, 'url'); - - final PictureInfoDecoder? decoder = networkPicture.decoder; - - // Update the theme of PictureProvider to include fontSize. - networkPicture.theme = SvgTheme( - fontSize: fontSize, - ); - - expect(networkPicture.decoder, isNotNull); - expect(networkPicture.decoder, isNot(equals(decoder))); - expect(currentTheme?.fontSize, equals(fontSize)); - }); - - test('FilePicture', () async { - const double fontSize = 26.0; - final FilePicture filePicture = FilePicture(decoderBuilder, MockFile()); - - final PictureInfoDecoder? decoder = filePicture.decoder; - - // Update the theme of PictureProvider to include fontSize. - filePicture.theme = SvgTheme( - fontSize: fontSize, - ); - - expect(filePicture.decoder, isNotNull); - expect(filePicture.decoder, isNot(equals(decoder))); - expect(currentTheme?.fontSize, equals(fontSize)); - }); - - test('MemoryPicture', () async { - const double fontSize = 26.0; - final MemoryPicture memoryPicture = - MemoryPicture(decoderBuilder, Uint8List(0)); - - final PictureInfoDecoder? decoder = memoryPicture.decoder; - - // Update the theme of PictureProvider to include fontSize. - memoryPicture.theme = SvgTheme( - fontSize: fontSize, - ); - - expect(memoryPicture.decoder, isNotNull); - expect(memoryPicture.decoder, isNot(equals(decoder))); - expect(currentTheme?.fontSize, equals(fontSize)); - }); - - test('StringPicture', () async { - const double fontSize = 26.0; - final StringPicture stringPicture = StringPicture(decoderBuilder, ''); - - final PictureInfoDecoder? decoder = stringPicture.decoder; - - // Update the theme of PictureProvider to include fontSize. - stringPicture.theme = SvgTheme( - fontSize: fontSize, - ); - - expect(stringPicture.decoder, isNotNull); - expect(stringPicture.decoder, isNot(equals(decoder))); - expect(currentTheme?.fontSize, equals(fontSize)); - }); - - test('ExactAssetPicture', () async { - const double fontSize = 26.0; - final ExactAssetPicture exactAssetPicture = - ExactAssetPicture(decoderBuilder, ''); - - final PictureInfoDecoder? decoder = exactAssetPicture.decoder; - - // Update the theme of PictureProvider to include fontSize. - exactAssetPicture.theme = SvgTheme( - fontSize: fontSize, - ); + exactAssetPicture.theme = newTheme; expect(exactAssetPicture.decoder, isNotNull); expect(exactAssetPicture.decoder, isNot(equals(decoder))); - expect(currentTheme?.fontSize, equals(fontSize)); + expect(currentTheme, equals(newTheme)); }); }); diff --git a/third_party/test/svg_parsers_test.dart b/third_party/test/svg_parsers_test.dart index 0472f62040be..2e2dd4c82d2e 100644 --- a/third_party/test/svg_parsers_test.dart +++ b/third_party/test/svg_parsers_test.dart @@ -114,49 +114,115 @@ void main() { test('Font size parsing tests', () { const double fontSize = 14.0; - expect(parseFontSize(null, fontSize: fontSize), isNull); - expect(parseFontSize('', fontSize: fontSize), isNull); - expect(parseFontSize('1', fontSize: fontSize), 1); - expect(parseFontSize(' 1 ', fontSize: fontSize), 1); - expect(parseFontSize('xx-small', fontSize: fontSize), 10); - expect(parseFontSize('x-small', fontSize: fontSize), 12); - expect(parseFontSize('small', fontSize: fontSize), 14); - expect(parseFontSize('medium', fontSize: fontSize), 18); - expect(parseFontSize('large', fontSize: fontSize), 22); - expect(parseFontSize('x-large', fontSize: fontSize), 26); - expect(parseFontSize('xx-large', fontSize: fontSize), 32); - - expect(parseFontSize('larger', fontSize: fontSize), - parseFontSize('large', fontSize: fontSize)); + const double xHeight = 7.0; + + expect( + parseFontSize(null, fontSize: fontSize, xHeight: xHeight), + isNull, + ); + expect( + parseFontSize('', fontSize: fontSize, xHeight: xHeight), + isNull, + ); + expect( + parseFontSize('1', fontSize: fontSize, xHeight: xHeight), + equals(1), + ); + expect( + parseFontSize(' 1 ', fontSize: fontSize, xHeight: xHeight), + equals(1), + ); + expect( + parseFontSize('xx-small', fontSize: fontSize, xHeight: xHeight), + equals(10), + ); + expect( + parseFontSize('x-small', fontSize: fontSize, xHeight: xHeight), + equals(12), + ); + expect( + parseFontSize('small', fontSize: fontSize, xHeight: xHeight), + equals(14), + ); + expect( + parseFontSize('medium', fontSize: fontSize, xHeight: xHeight), + equals(18), + ); + expect( + parseFontSize('large', fontSize: fontSize, xHeight: xHeight), + equals(22), + ); + expect( + parseFontSize('x-large', fontSize: fontSize, xHeight: xHeight), + equals(26), + ); + expect( + parseFontSize('xx-large', fontSize: fontSize, xHeight: xHeight), + equals(32), + ); + expect( - parseFontSize('larger', - fontSize: fontSize, - parentValue: parseFontSize('large', fontSize: fontSize)), - parseFontSize('large', fontSize: fontSize)! * 1.2); - expect(parseFontSize('smaller', fontSize: fontSize), - parseFontSize('small', fontSize: fontSize)); + parseFontSize('larger', fontSize: fontSize, xHeight: xHeight), + equals(parseFontSize('large', fontSize: fontSize, xHeight: xHeight)), + ); + expect( + parseFontSize( + 'larger', + fontSize: fontSize, + xHeight: xHeight, + parentValue: + parseFontSize('large', fontSize: fontSize, xHeight: xHeight), + ), + equals( + parseFontSize('large', fontSize: fontSize, xHeight: xHeight)! * 1.2, + ), + ); expect( - parseFontSize('smaller', - fontSize: fontSize, - parentValue: parseFontSize('large', fontSize: fontSize)), - parseFontSize('large', fontSize: fontSize)! / 1.2); + parseFontSize('smaller', fontSize: fontSize, xHeight: xHeight), + equals( + parseFontSize('small', fontSize: fontSize, xHeight: xHeight), + ), + ); + expect( + parseFontSize( + 'smaller', + fontSize: fontSize, + xHeight: xHeight, + parentValue: + parseFontSize('large', fontSize: fontSize, xHeight: xHeight), + ), + equals( + parseFontSize('large', fontSize: fontSize, xHeight: xHeight)! / 1.2, + ), + ); - expect(() => parseFontSize('invalid', fontSize: fontSize), + expect(() => parseFontSize('invalid', fontSize: fontSize, xHeight: xHeight), throwsA(const TypeMatcher())); }); test('relative font size tests', () { const double fontSize = 26.0; + const double xHeight = 14.0; expect( - parseFontSize('4em', fontSize: fontSize), + parseFontSize('4em', fontSize: fontSize, xHeight: xHeight), equals(4 * fontSize), ); expect( - parseFontSize(' 2em ', fontSize: fontSize), + parseFontSize(' 2em ', fontSize: fontSize, xHeight: xHeight), equals(2 * fontSize), ); + + expect( + parseFontSize('4ex', fontSize: fontSize, xHeight: xHeight), + equals(4 * xHeight), + ); + + expect( + parseFontSize(' 2ex ', fontSize: fontSize, xHeight: xHeight), + equals(2 * xHeight), + ); }); test('Check no child with id for svg', () async { @@ -780,4 +846,189 @@ BAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" x="1em" y="0.5em" width="2em" height="1.5em" / expect(image.size, equals(expectedSize)); }); }); + + group('calculates ex units based on the x-height for', () { + test('svg (width, height)', () async { + const String svgStr = ''' + +'''; + + const double fontSize = 26.0; + const double xHeight = 11.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + xHeight: xHeight, + ), + ); + + expect(root.viewport.width, equals(xHeight * 5)); + expect(root.viewport.height, equals(xHeight * 6)); + }); + + test('use (x, y)', () async { + const String svgStr = ''' + + + + +'''; + + const double fontSize = 26.0; + const double xHeight = 11.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + xHeight: xHeight, + ), + ); + + final DrawableGroup? circle = find(root, 'anotherCircle'); + + const double expectedX = xHeight * 2; + const double expectedY = xHeight * 4; + + expect(circle, isNotNull); + expect( + circle!.transform, + equals( + (Matrix4.identity()..translate(expectedX, expectedY)).storage, + ), + ); + }); + + test('text (x, y)', () async { + const String svgStr = ''' + + Test + +'''; + + const double fontSize = 26.0; + const double xHeight = 11.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + xHeight: xHeight, + ), + ); + + final DrawableText? text = find(root, 'text'); + + const Offset expectedOffset = Offset(xHeight * 2, xHeight * 4); + + expect(text, isNotNull); + expect(text!.offset, equals(expectedOffset)); + }); + + test('radialGradient (cx, cy, r, fx, fy)', () async { + const String svgStr = ''' + + + + + + + + +'''; + + const double fontSize = 26.0; + const double xHeight = 11.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + xHeight: xHeight, + ), + ); + + final DrawableRadialGradient? gradient = + root.definitions.getGradient('url(#gradient)'); + + expect(gradient, isNotNull); + + const Offset expectedOffset = Offset(xHeight * 1, xHeight * 2); + const double expectedRadius = xHeight * 1.1; + const Offset expectedFocal = Offset(xHeight * 1.5, xHeight * 1.6); + + expect(gradient, isNotNull); + expect(gradient!.center, equals(expectedOffset)); + expect(gradient.radius, equals(expectedRadius)); + expect(gradient.focal, equals(expectedFocal)); + }); + + test('linearGradient (x1, y1, x2, y2)', () async { + const String svgStr = ''' + + + + + + + +'''; + + const double fontSize = 26.0; + const double xHeight = 11.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + xHeight: xHeight, + ), + ); + + final DrawableLinearGradient? gradient = + root.definitions.getGradient('url(#gradient)'); + + expect(gradient, isNotNull); + + const Offset expectedFromOffset = Offset(xHeight * 1, xHeight * 1.75); + const Offset expectedToOffset = Offset(xHeight * 1.5, xHeight * 1.6); + + expect(gradient, isNotNull); + expect(gradient!.from, equals(expectedFromOffset)); + expect(gradient.to, equals(expectedToOffset)); + }); + + test('image (x, y, width, height)', () async { + const String svgStr = ''' + + + +'''; + + const double fontSize = 26.0; + const double xHeight = 11.0; + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse( + svgStr, + theme: const SvgTheme( + fontSize: fontSize, + xHeight: xHeight, + ), + ); + + final DrawableRasterImage? image = + find(root, 'image'); + + const Offset expectedOffset = Offset(xHeight * 1, xHeight * 0.5); + const Size expectedSize = Size(xHeight * 2, xHeight * 1.5); + + expect(image, isNotNull); + expect(image!.offset, equals(expectedOffset)); + expect(image.size, equals(expectedSize)); + }); + }); } diff --git a/third_party/test/theme_test.dart b/third_party/test/theme_test.dart index 998d45dd147d..71b88879ee35 100644 --- a/third_party/test/theme_test.dart +++ b/third_party/test/theme_test.dart @@ -41,6 +41,31 @@ void main() { ), ); }); + + test('sets xHeight', () { + const double xHeight = 8.0; + + expect( + SvgTheme( + fontSize: 26.0, + xHeight: xHeight, + ).xHeight, + equals(xHeight), + ); + }); + + test( + 'sets xHeight as fontSize divided by 2 ' + 'by default', () { + const double fontSize = 16.0; + + expect( + SvgTheme( + fontSize: fontSize, + ).xHeight, + equals(fontSize / 2), + ); + }); }); test('supports value equality', () { @@ -48,11 +73,13 @@ void main() { SvgTheme( currentColor: Color(0xFF6F2173), fontSize: 14.0, + xHeight: 6.0, ), equals( SvgTheme( currentColor: Color(0xFF6F2173), fontSize: 14.0, + xHeight: 6.0, ), ), ); diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index bb51e695b5af..4508a2cd8bc7 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -771,7 +771,7 @@ void main() { ); await tester.pumpAndSettle(); - await _checkWidgetAndGolden(key, 'circle.em.png'); + await _checkWidgetAndGolden(key, 'circle.em_ex.png'); }); testWidgets('rect (x, y, width, height, rx, ry)', @@ -795,7 +795,7 @@ void main() { ); await tester.pumpAndSettle(); - await _checkWidgetAndGolden(key, 'rect.em.png'); + await _checkWidgetAndGolden(key, 'rect.em_ex.png'); }); testWidgets('ellipse (cx, cy, rx, ry)', (WidgetTester tester) async { @@ -818,10 +818,10 @@ void main() { ); await tester.pumpAndSettle(); - await _checkWidgetAndGolden(key, 'ellipse.em.png'); + await _checkWidgetAndGolden(key, 'ellipse.em_ex.png'); }); - testWidgets('line (x1, x2, y1, y2)', (WidgetTester tester) async { + testWidgets('line (x1, y1, x2, y2)', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); const String svgStr = ''' @@ -842,7 +842,115 @@ void main() { ); await tester.pumpAndSettle(); - await _checkWidgetAndGolden(key, 'line.em.png'); + await _checkWidgetAndGolden(key, 'line.em_ex.png'); + }); + }); + + group('SvgPicture respects ex units', () { + testWidgets('circle (cx, cy, r)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme( + fontSize: 1500, + xHeight: 600, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'circle.em_ex.png'); + }); + + testWidgets('rect (x, y, width, height, rx, ry)', + (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme( + fontSize: 300, + xHeight: 100, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'rect.em_ex.png'); + }); + + testWidgets('ellipse (cx, cy, rx, ry)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme( + fontSize: 300, + xHeight: 100, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'ellipse.em_ex.png'); + }); + + testWidgets('line (x1, y1, x2, y2)', (WidgetTester tester) async { + final GlobalKey key = GlobalKey(); + + const String svgStr = ''' + + + + +'''; + + await tester.pumpWidget( + RepaintBoundary( + key: key, + child: SvgPicture.string( + svgStr, + theme: const SvgTheme( + fontSize: 300, + xHeight: 100, + ), + ), + ), + ); + + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'line.em_ex.png'); }); }); diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index f208960b86e3..81733bcf6e8f 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -84,6 +84,7 @@ void main() { parseViewBox( svgWithViewBoxAndWidthHeight.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, )! .size, const Size(50, 50)); @@ -91,6 +92,7 @@ void main() { parseViewBox( svgWithViewBox.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, )! .viewBoxRect, rect); @@ -98,6 +100,7 @@ void main() { parseViewBox( svgWithViewBox.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, )! .viewBoxOffset, Offset.zero); @@ -105,6 +108,7 @@ void main() { parseViewBox( svgWithViewBoxAndWidthHeight.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, )! .viewBoxRect, rect); @@ -112,6 +116,7 @@ void main() { parseViewBox( svgWithWidthHeight.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, )! .viewBoxRect, rect); @@ -119,6 +124,7 @@ void main() { parseViewBox( svgWithNoSizeInfo.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, nullOk: true, ), null); @@ -126,12 +132,14 @@ void main() { () => parseViewBox( svgWithNoSizeInfo.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, ), throwsStateError); expect( parseViewBox( svgWithViewBoxMinXMinY.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, )! .viewBoxRect, rect); @@ -139,6 +147,7 @@ void main() { parseViewBox( svgWithViewBoxMinXMinY.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, )! .viewBoxOffset, const Offset(-42.0, -56.0)); @@ -182,6 +191,7 @@ void main() { parseDashOffset( abs.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, ), equals(const DashOffset.absolute(20.0)), ); @@ -190,6 +200,7 @@ void main() { parseDashOffset( pct.attributes.toAttributeMap(), fontSize: 14.0, + xHeight: 7.0, ), equals(DashOffset.percentage(0.2)), ); @@ -257,6 +268,7 @@ void main() { null, currentColor: currentColor, fontSize: 14.0, + xHeight: 7.0, ); expect( @@ -279,6 +291,7 @@ void main() { null, currentColor: currentColor, fontSize: 14.0, + xHeight: 7.0, ); expect( @@ -287,84 +300,165 @@ void main() { ); }); - test( - 'calculates em units based on the font size ' - 'for stroke width', () { - final XmlStartElementEvent svg = - parseEvents('').first - as XmlStartElementEvent; - - const double fontSize = 26.0; - - final DrawableStyle svgStyle = parseStyle( - 'test', - svg.attributes.toAttributeMap(), - DrawableDefinitionServer(), - null, - null, - fontSize: fontSize, - ); - - expect( - svgStyle.stroke?.strokeWidth, - equals(fontSize * 2), - ); - }); - - test( - 'calculates em units based on the font size ' - 'for dash array', () { - final XmlStartElementEvent svg = parseEvents( - '', - ).first as XmlStartElementEvent; - - const double fontSize = 26.0; - - final DrawableStyle svgStyle = parseStyle( - 'test', - svg.attributes.toAttributeMap(), - DrawableDefinitionServer(), - null, - null, - fontSize: fontSize, - ); - - expect( - [ - svgStyle.dashArray!.next, - svgStyle.dashArray!.next, - svgStyle.dashArray!.next, - ], - equals([ - fontSize * 0.2, - fontSize * 0.5, - 10, - ]), - ); + group('calculates em units based on the font size for', () { + test('stroke width', () { + final XmlStartElementEvent svg = + parseEvents('').first + as XmlStartElementEvent; + + const double fontSize = 26.0; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + fontSize: fontSize, + xHeight: 7.0, + ); + + expect( + svgStyle.stroke?.strokeWidth, + equals(fontSize * 2), + ); + }); + + test('dash array', () { + final XmlStartElementEvent svg = parseEvents( + '', + ).first as XmlStartElementEvent; + + const double fontSize = 26.0; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + fontSize: fontSize, + xHeight: 7.0, + ); + + expect( + [ + svgStyle.dashArray!.next, + svgStyle.dashArray!.next, + svgStyle.dashArray!.next, + ], + equals([ + fontSize * 0.2, + fontSize * 0.5, + 10, + ]), + ); + }); + + test('dash offset', () { + final XmlStartElementEvent svg = parseEvents( + '', + ).first as XmlStartElementEvent; + + const double fontSize = 26.0; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + fontSize: fontSize, + xHeight: 7.0, + ); + + expect( + svgStyle.dashOffset, + equals(const DashOffset.absolute(fontSize * 0.15)), + ); + }); }); - test( - 'calculates em units based on the font size ' - 'for dash offset', () { - final XmlStartElementEvent svg = parseEvents( - '', - ).first as XmlStartElementEvent; - - const double fontSize = 26.0; - - final DrawableStyle svgStyle = parseStyle( - 'test', - svg.attributes.toAttributeMap(), - DrawableDefinitionServer(), - null, - null, - fontSize: fontSize, - ); - - expect( - svgStyle.dashOffset, - equals(const DashOffset.absolute(fontSize * 0.15)), - ); + group('calculates ex units based on the x-height for', () { + test('stroke width', () { + final XmlStartElementEvent svg = + parseEvents('').first + as XmlStartElementEvent; + + const double fontSize = 26.0; + const double xHeight = 11.0; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + fontSize: fontSize, + xHeight: xHeight, + ); + + expect( + svgStyle.stroke?.strokeWidth, + equals(xHeight * 2), + ); + }); + + test('dash array', () { + final XmlStartElementEvent svg = parseEvents( + '', + ).first as XmlStartElementEvent; + + const double fontSize = 26.0; + const double xHeight = 11.0; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + fontSize: fontSize, + xHeight: xHeight, + ); + + expect( + [ + svgStyle.dashArray!.next, + svgStyle.dashArray!.next, + svgStyle.dashArray!.next, + ], + equals([ + xHeight * 0.2, + xHeight * 0.5, + 10, + ]), + ); + }); + + test('dash offset', () { + final XmlStartElementEvent svg = parseEvents( + '', + ).first as XmlStartElementEvent; + + const double fontSize = 26.0; + const double xHeight = 11.0; + + final DrawableStyle svgStyle = parseStyle( + 'test', + svg.attributes.toAttributeMap(), + DrawableDefinitionServer(), + null, + null, + fontSize: fontSize, + xHeight: xHeight, + ); + + expect( + svgStyle.dashOffset, + equals(const DashOffset.absolute(xHeight * 0.15)), + ); + }); }); }); } From 00eee0af1243c25c287e019af8a8c974ea00bcbe Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Jan 2022 13:03:56 -0800 Subject: [PATCH 421/512] Fix but in element fills, analysis cleanup --- third_party/CHANGELOG.md | 5 +++++ .../assets/simple/fill_inheritence_test.svg | 4 ++++ .../example/assets/simple/use_fill_test.svg | 8 +++++++ .../golden/simple/fill_inheritence_test.png | Bin 0 -> 588 bytes third_party/golden/simple/use_fill_test.png | Bin 0 -> 718 bytes third_party/lib/src/svg/xml_parsers.dart | 21 ++++++++++-------- third_party/lib/src/vector_drawable.dart | 3 +++ third_party/test/default_theme_test.dart | 2 -- third_party/test/picture_cache_test.dart | 1 - third_party/test/picture_provider_test.dart | 1 - 10 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 third_party/example/assets/simple/fill_inheritence_test.svg create mode 100644 third_party/example/assets/simple/use_fill_test.svg create mode 100644 third_party/golden/simple/fill_inheritence_test.png create mode 100644 third_party/golden/simple/use_fill_test.png diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 69d1cbf228f3..ccd25bf3075e 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## UNRELEASED + +- Fix bug with incorrect fills in some cases of `` elements. +- Analysis cleanup of Dart code. + ## 1.0.0 - New widget/RenderObject implementation to avoid rebuilds/paints when diff --git a/third_party/example/assets/simple/fill_inheritence_test.svg b/third_party/example/assets/simple/fill_inheritence_test.svg new file mode 100644 index 000000000000..93a8222771c6 --- /dev/null +++ b/third_party/example/assets/simple/fill_inheritence_test.svg @@ -0,0 +1,4 @@ + + + + diff --git a/third_party/example/assets/simple/use_fill_test.svg b/third_party/example/assets/simple/use_fill_test.svg new file mode 100644 index 000000000000..3bf0fe96a3e1 --- /dev/null +++ b/third_party/example/assets/simple/use_fill_test.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/third_party/golden/simple/fill_inheritence_test.png b/third_party/golden/simple/fill_inheritence_test.png new file mode 100644 index 0000000000000000000000000000000000000000..ccdf26fc6206c013092eb2e9145c0f2a8a63d7a1 GIT binary patch literal 588 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>pxif47srr_Id89SVZfqx%Ztxj?kO`9=!B1p#5)z4*}Q$iB}$hBh0 literal 0 HcmV?d00001 diff --git a/third_party/golden/simple/use_fill_test.png b/third_party/golden/simple/use_fill_test.png new file mode 100644 index 0000000000000000000000000000000000000000..aafff9f160b3ee38cd8c65150a40c482ff01fc5f GIT binary patch literal 718 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q`IPZ!6KiaBquZ}eqx6mUJrHc>p~SZ+$eL|(RYk}oWEq_(W;df>e_{mbR3 zY~BxxpWkJEU@y$U(&!*SXQE~LU1q;xncd8bg=d#Wzp$Py5 Cx3{SP literal 0 HcmV?d00001 diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index fd4872a857dc..27b708410f30 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -298,7 +298,17 @@ DrawablePaint? parseFill( ); } - if (rawFill == '' && parentFill == DrawablePaint.empty) { + final Color? fillColor = _determineFillColor( + parentFill?.color, + rawFill, + opacity, + rawOpacity != '' || rawFillOpacity != '', + defaultFillColor, + currentColor, + ); + + if (rawFill == '' && + (fillColor == null || parentFill == DrawablePaint.empty)) { return null; } if (rawFill == 'none') { @@ -307,14 +317,7 @@ DrawablePaint? parseFill( return DrawablePaint( PaintingStyle.fill, - color: _determineFillColor( - parentFill?.color, - rawFill, - opacity, - rawOpacity != '' || rawFillOpacity != '', - defaultFillColor, - currentColor, - ), + color: fillColor, ); } diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 4eabe0b20907..000b31aad1c4 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -326,6 +326,9 @@ class DrawablePaint { @override String toString() { + if (identical(this, DrawablePaint.empty)) { + return 'DrawablePaint{}'; + } return 'DrawablePaint{$style, color: $color, shader: $shader, blendMode: $blendMode, ' 'colorFilter: $colorFilter, isAntiAlias: $isAntiAlias, filterQuality: $filterQuality, ' 'maskFilter: $maskFilter, strokeCap: $strokeCap, strokeJoin: $strokeJoin, ' diff --git a/third_party/test/default_theme_test.dart b/third_party/test/default_theme_test.dart index 2ee9dc9877dd..f64098e422ff 100644 --- a/third_party/test/default_theme_test.dart +++ b/third_party/test/default_theme_test.dart @@ -1,7 +1,5 @@ // ignore_for_file: prefer_const_constructors -import 'dart:ui'; - import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_test/flutter_test.dart'; diff --git a/third_party/test/picture_cache_test.dart b/third_party/test/picture_cache_test.dart index b0358fd58b84..29e1bdd419b2 100644 --- a/third_party/test/picture_cache_test.dart +++ b/third_party/test/picture_cache_test.dart @@ -1,7 +1,6 @@ import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/src/picture_cache.dart'; -import 'package:flutter_svg/src/svg/theme.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:xml/xml.dart'; diff --git a/third_party/test/picture_provider_test.dart b/third_party/test/picture_provider_test.dart index b72ac51fe274..0756860092ae 100644 --- a/third_party/test/picture_provider_test.dart +++ b/third_party/test/picture_provider_test.dart @@ -5,7 +5,6 @@ import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_svg/src/svg/theme.dart'; import 'package:mocktail/mocktail.dart'; import 'package:test/test.dart'; From 6f76375949402a05176aa8c2aea277dadcdf438b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Jan 2022 16:12:24 -0800 Subject: [PATCH 422/512] Fix bug where empty group can affect rendering --- third_party/CHANGELOG.md | 1 + .../example/assets/simple/empty_group.svg | 6 ++++++ third_party/golden/simple/empty_group.png | Bin 0 -> 1888 bytes third_party/lib/src/svg/parser_state.dart | 5 ++++- 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 third_party/example/assets/simple/empty_group.svg create mode 100644 third_party/golden/simple/empty_group.png diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index ccd25bf3075e..3086e9fe63c8 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -4,6 +4,7 @@ - Fix bug with incorrect fills in some cases of `` elements. - Analysis cleanup of Dart code. +- Fix bug where self-closing `` tags could alter rendering. ## 1.0.0 diff --git a/third_party/example/assets/simple/empty_group.svg b/third_party/example/assets/simple/empty_group.svg new file mode 100644 index 000000000000..893be543b5a3 --- /dev/null +++ b/third_party/example/assets/simple/empty_group.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/third_party/golden/simple/empty_group.png b/third_party/golden/simple/empty_group.png new file mode 100644 index 0000000000000000000000000000000000000000..53c52b10b268d7d4c31a2b65bcbae279fb2e66c8 GIT binary patch literal 1888 zcmeHI`#aMM7+)-wijlcwG^-`z=%OaM48tyuOC#jcoR-^22WJZj-?@}l&AoGoI(#!6 zRI=3M(kUUKgmE;ES*@a6VshPCPyfXE;k?iDzVGvS-skze@B8`TeKS4WT(+ugSAjqv zTZsfbMV>ppJ4{I)YkX@<cFQ#B^3llw!U- znjdtOrIsWZgJ!lvuL_-iBGi{I3@-eW059se-}vS!!TF@vB`R|As9zHm#l%2YQr>r; zOZrSVmGNT6TO;Se5w4xrw`C3k(=19rPSM^jKwMk{vPCU2N@sEu{m==9jjGfhrCLwT zWwj)gHx~Po8YqH^Rvbz-j@DOaHMcI^EL@ei2B*GUAjBytM1zNSo7pa>@{7m9KaUqq zM$c@4iafeNi)ux#1v2Z(l>lg;XRXXl`^G{P3x$HDu<(Kad> zaKa`$f~dA$0Tw+p*ysoYp>!H$X2!i5g~6jR>aK+0wXxXoyQg8`u5zPYYm2@7hWOrv zJwxd@(qDSH^^d+JY}sO%l>>Vq)1Zb>`T9_I!>j|t{5w&D44aKi!z_(W24m-J6y$v} zK}Er~ARQo&_?0!eXfwh3%_#tfBq_IjQg=1Gn~hN# zS`n~}!RGeG+8tjJkEm1uKh(u>jcSUQJjOGFdF6h!?ErvN^|i{1S|QK%tm3-31%aH@ z3-FE&B;`IyenA~JxqR;|qPB2{0yGB4Ut%K3H$R<9%%8aCSSm_LDMNMLE*fRkNqZUl zo2x7@1#;3Pc+{PtT%n1`G7lz3{QZI0pm+UU(^6)Ed&|=%?~8EYG5VYVIpW}SXY$0( zrVE!N^e-ZS$ESq>{3Z-WV(a~jbmc~kl^7<*_;rDe0|j;L9hHpb5qfXEoLn1^GPjox zdxjXE=(zsqX4nz_GyhN*DDXJN^!nhzaGsTU;Ic0}w599n#hn?r=JKm0zjCQQOlbxy zeUV|ze+GPmp|fP3TqB`w|A0+=;5s&`f;q1xIP9zgSaU)1nh;8iC@}u(j%mU+l~-zrL5J=`?=8z)1>VcJKKp2o;(0cTKXBsq zXyz$K*h_MIhE+tAc`bY8(3vRByBFjpHIBHP(HF9s`V)Ok! zrVHLt{EDvc{xovuq&brfqEkqLRSn|fMhGv(_-!R}oEz`6R0Fdh_xkyXl2EXZ5nI|IGGAth5-C*emf?&3oZnB3W8*dC&kBS;re7 zH(MS}%l_&BK+3Lh3^s0oD(JwV`{1x36kL9=QUDx85r8NuZ1}(MpOj=(ZEPUK? g(SvgParserState parserState, bool warningsAsErrors) { + // if (parserState._currentStartElement?.isSelfClosing == true) { + // return null; + // } final DrawableParent parent = parserState.currentGroup!; final Color? color = parseColor(parserState.attribute('color', def: null)) ?? parent.color; @@ -916,7 +919,7 @@ class SvgParserState { this.theme, this._key, this._warningsAsErrors, - ) + ) // ignore: unnecessary_null_comparison : assert(events != null), _eventIterator = events.iterator; From b2a5a91e387d23892d8fc3e4b243d80a583f3d00 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Jan 2022 16:13:45 -0800 Subject: [PATCH 423/512] oops --- .../example/assets/simple/empty_group.svg | 2 +- third_party/golden/simple/empty_group.png | Bin 1888 -> 4013 bytes third_party/lib/src/svg/parser_state.dart | 6 +++--- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/third_party/example/assets/simple/empty_group.svg b/third_party/example/assets/simple/empty_group.svg index 893be543b5a3..af423cf01068 100644 --- a/third_party/example/assets/simple/empty_group.svg +++ b/third_party/example/assets/simple/empty_group.svg @@ -3,4 +3,4 @@ - \ No newline at end of file + diff --git a/third_party/golden/simple/empty_group.png b/third_party/golden/simple/empty_group.png index 53c52b10b268d7d4c31a2b65bcbae279fb2e66c8..a99844327c1bfac8f198f09e248975e2ffc2e37a 100644 GIT binary patch literal 4013 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 literal 1888 zcmeHI`#aMM7+)-wijlcwG^-`z=%OaM48tyuOC#jcoR-^22WJZj-?@}l&AoGoI(#!6 zRI=3M(kUUKgmE;ES*@a6VshPCPyfXE;k?iDzVGvS-skze@B8`TeKS4WT(+ugSAjqv zTZsfbMV>ppJ4{I)YkX@<cFQ#B^3llw!U- znjdtOrIsWZgJ!lvuL_-iBGi{I3@-eW059se-}vS!!TF@vB`R|As9zHm#l%2YQr>r; zOZrSVmGNT6TO;Se5w4xrw`C3k(=19rPSM^jKwMk{vPCU2N@sEu{m==9jjGfhrCLwT zWwj)gHx~Po8YqH^Rvbz-j@DOaHMcI^EL@ei2B*GUAjBytM1zNSo7pa>@{7m9KaUqq zM$c@4iafeNi)ux#1v2Z(l>lg;XRXXl`^G{P3x$HDu<(Kad> zaKa`$f~dA$0Tw+p*ysoYp>!H$X2!i5g~6jR>aK+0wXxXoyQg8`u5zPYYm2@7hWOrv zJwxd@(qDSH^^d+JY}sO%l>>Vq)1Zb>`T9_I!>j|t{5w&D44aKi!z_(W24m-J6y$v} zK}Er~ARQo&_?0!eXfwh3%_#tfBq_IjQg=1Gn~hN# zS`n~}!RGeG+8tjJkEm1uKh(u>jcSUQJjOGFdF6h!?ErvN^|i{1S|QK%tm3-31%aH@ z3-FE&B;`IyenA~JxqR;|qPB2{0yGB4Ut%K3H$R<9%%8aCSSm_LDMNMLE*fRkNqZUl zo2x7@1#;3Pc+{PtT%n1`G7lz3{QZI0pm+UU(^6)Ed&|=%?~8EYG5VYVIpW}SXY$0( zrVE!N^e-ZS$ESq>{3Z-WV(a~jbmc~kl^7<*_;rDe0|j;L9hHpb5qfXEoLn1^GPjox zdxjXE=(zsqX4nz_GyhN*DDXJN^!nhzaGsTU;Ic0}w599n#hn?r=JKm0zjCQQOlbxy zeUV|ze+GPmp|fP3TqB`w|A0+=;5s&`f;q1xIP9zgSaU)1nh;8iC@}u(j%mU+l~-zrL5J=`?=8z)1>VcJKKp2o;(0cTKXBsq zXyz$K*h_MIhE+tAc`bY8(3vRByBFjpHIBHP(HF9s`V)Ok! zrVHLt{EDvc{xovuq&brfqEkqLRSn|fMhGv(_-!R}oEz`6R0Fdh_xkyXl2EXZ5nI|IGGAth5-C*emf?&3oZnB3W8*dC&kBS;re7 zH(MS}%l_&BK+3Lh3^s0oD(JwV`{1x36kL9=QUDx85r8NuZ1}(MpOj=(ZEPUK? g(SvgParserState parserState, bool warningsAsErrors) { - // if (parserState._currentStartElement?.isSelfClosing == true) { - // return null; - // } + if (parserState._currentStartElement?.isSelfClosing == true) { + return null; + } final DrawableParent parent = parserState.currentGroup!; final Color? color = parseColor(parserState.attribute('color', def: null)) ?? parent.color; From 12950f7524dbd1702c41978f51a75d9257a44942 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Jan 2022 16:41:02 -0800 Subject: [PATCH 424/512] Avoid invalid dasharrays --- third_party/CHANGELOG.md | 1 + .../assets/simple/invalid_dash_array.svg | 3 +++ .../golden/simple/invalid_dash_array.png | Bin 0 -> 2732 bytes third_party/lib/src/svg/xml_parsers.dart | 16 ++++++++++++---- 4 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 third_party/example/assets/simple/invalid_dash_array.svg create mode 100644 third_party/golden/simple/invalid_dash_array.png diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 3086e9fe63c8..03875dfaa62f 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -5,6 +5,7 @@ - Fix bug with incorrect fills in some cases of `` elements. - Analysis cleanup of Dart code. - Fix bug where self-closing `` tags could alter rendering. +- Fix bug where an invalid `@stroke-dasharray` could cause an infinite loop. ## 1.0.0 diff --git a/third_party/example/assets/simple/invalid_dash_array.svg b/third_party/example/assets/simple/invalid_dash_array.svg new file mode 100644 index 000000000000..24b0b96cf0c5 --- /dev/null +++ b/third_party/example/assets/simple/invalid_dash_array.svg @@ -0,0 +1,3 @@ +a + + \ No newline at end of file diff --git a/third_party/golden/simple/invalid_dash_array.png b/third_party/golden/simple/invalid_dash_array.png new file mode 100644 index 0000000000000000000000000000000000000000..afb5d1ec3a8f32bba6f10a71d10257e9efd812ba GIT binary patch literal 2732 zcmeHJ|3A~)AJ@1n<@@zL+d}zzx#&h_8Lg1MNHyOnVZK(jW@7SLS8T#iTE3T1GT&1| ztxMT3T(si)cCn>l+Z{3A;`8q3&*$;^3qI%ZIOjah<9vCZ=kuKNJTHpJ85ae49eF7! zDFruIlqXQLeq^vLP}X?YmH^c*oTrPkRBiu0KG2ZCIlEl|1BnO@AxlZgquo$W7vhTq z69Z>;`P%QqMx4J4%5)TEDW$4^s9LC?8XoOBqM9wu&E@76Z49h@ENZ01DE4`pC|4OD zqGW*dv4&vNET@j6m)x_Wy~^aS7lcle2o7NmBBJA5v(4a_g_~3PlH%8~L?Y2#s((d} zp(GWKkpUTlWjvI@k6_A3C)mGkBc*;KNy&r6=bF)yP37y9(ygOXeix(g>jjoQm&L9q zl;R#2&zkREC=_7o{CG$ASjt?(-W( z`1tm(C25t!mZ{{QruGWB*;8q%b~4zmA?(5H%bC@|fx%hGGk|h8*XJji1K;Aya-yIe z2T~J5r=8MocB`wfs^%=wzSi2*5B7#u<3_)KpO`_NeekxJaK6sBy7%%lcfc}_;Rfh7 ze#@zccdZ0E3}BeEpE~RW>Z*|A9qBq>@4C;ROZToa3rqGvHK>L(%O3Qqqo?r$2Yct7 zHZ=ol8bq?V8Lhs7wAO_K%!luZbaeG{^Q%5hl$+(5H8!@Iz#+e+_&+>r70W<9lNQfM za*#p(8qo4ufe;TMzY;Yq;Ta>}2#BPjFg=?73(`IfDt9gjU07g9V8TN!5W+FXdjGdD zv+Bar3U7+SQGj^3QZDH6-tr5ztYuBJ(;uu3+Z*B}%p``+g&Gb|w6jJyk5Lo01exFW zyGncTxiI}og0;!r7;M!?$_ei1y-h43`27k2zzN|6O|mAjn}H6!lO8;^IF17iQRNv|HTU_S-nOg?d@>L%62AHxe!FuX`MkMR{Ez8xIpKqYYrT{cz%9dk z)3(Lgj(O{m3->$2Ee}LI;7`@~R;O+Ew@#3>6jg#9+i9IAj5cTbzM#i~IuPte`|L>0 zqG<+S*^qoHs0$ZRcO%>jEf?HMVRdz{`%wJC96`;)uY&L7aYzs4J0d5-^81h7-tZ5u z^VTKvcf5z)AA#kfq^*jRZ)^`v0y8T2Xmt`b8f=w28=7WEaC2MMm0pdflB1)8V_=!g z_`r)=U!V$=j%}=?XHMHs7tl%N2p3T|djHI#>3N!~_Oh*N&3jJzPF^pT9-7 zc~5&+qfpNL$MYck>vc$!^saU!Y=6kcp*0vnjUDw#c4#;z&SZJvmetRR_3pfr#@i)< z4TqI&6MJy`N1QZM8Bb_*1=M?D-#M*=^Oc1x*^QZB>~k;G+ba(@GHVVPmYT?Vz3air6{i8Wh~gC>=KKNZjcO969eAV)m;w7 zH&rF4)Ogfz3XgX7RWgqx7R?$ll-?=f__0UK_h~aAk1qqOav}pXAmzm5Q4H|P05-qj z2f{*HygW~Dg^w(DiN)fEDY@yi$Qp~}?_-XItpn3218bYS==lsTx*1Jd$<*s6Mql+g zMQA@?f_N=T{3}K16->immLuWX?0da9k0NuIKPk*~8iG02fd0M6%RaVIf3c~o;c(sz% zGF@lTb%v>%1?d$kA698e15=0Lh+K(tj4C zZno$AY(uF(Wl57HmHwx|P43ixL?poT|L>v7|2zJdR%=i*cYgG1UPu`baZ0%zKZB}u HzI6NFKJe#r literal 0 HcmV?d00001 diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index 0403421c0a01..cd0cc1fa52c6 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -139,10 +139,18 @@ CircularIntervalList? parseDashArray( } final List parts = rawDashArray!.split(RegExp(r'[ ,]+')); - return CircularIntervalList(parts - .map((String part) => - parseDoubleWithUnits(part, fontSize: fontSize, xHeight: xHeight)!) - .toList()); + final List doubles = []; + for (final String part in parts) { + final double dashOffset = + parseDoubleWithUnits(part, fontSize: fontSize, xHeight: xHeight)!; + if (dashOffset != 0) { + doubles.add(dashOffset); + } + } + if (doubles.isEmpty) { + return null; + } + return CircularIntervalList(doubles); } /// Parses a @stroke-dashoffset into a [DashOffset]. From fbcc7aefe761c0e14e7599e4d92bcd0de03f4f03 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 11 Jan 2022 11:36:23 -0800 Subject: [PATCH 425/512] Fix bug in dash array update: zero values should be acceptable in some cases --- third_party/example/assets/simple/dash_zero.svg | 3 +++ third_party/golden/simple/dash_zero.png | Bin 0 -> 775 bytes third_party/lib/src/svg/xml_parsers.dart | 6 ++++-- 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 third_party/example/assets/simple/dash_zero.svg create mode 100644 third_party/golden/simple/dash_zero.png diff --git a/third_party/example/assets/simple/dash_zero.svg b/third_party/example/assets/simple/dash_zero.svg new file mode 100644 index 000000000000..b4c5925544d9 --- /dev/null +++ b/third_party/example/assets/simple/dash_zero.svg @@ -0,0 +1,3 @@ + + + diff --git a/third_party/golden/simple/dash_zero.png b/third_party/golden/simple/dash_zero.png new file mode 100644 index 0000000000000000000000000000000000000000..65f09b1ccfb2651847388280262e9104f0962dfe GIT binary patch literal 775 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q{$o-U3d6?5L+y_mb$ON8yg=J4;fJDAjEXK)=5WhqZ6chKtaR*>Dn6683C z&x3Vli39si{nr`ct5esuh^l=5EhlJYtiS)*nU4-EK*Pxg2kw7;`}OPB(pR1bBzCRq z{{8#+j(z+3u4b8fovn9U$z*(CTkf0hzb$0=7GM2SzQyZ<_|hqlo<3FWTJ+g zm*%QfQn@kq8-Iv|tq!%ZwLN|=7AWEh)NOw+pY>tzid9;hbh=NU zKFxpiV&>qR*Jh=2Lp?$);6O*-efW;YyQ*d1Zu;E>SJU?AOoSg~w(?3Y^m zuOat1I5rn%eJYJLKlvl~_OZ0hol`E|Hod*)jN4_Ci9u3t^OfF9{{Q&VuxnAru64?X z^u+d9e)ZUPJ2xd#OpuAG*{1mb17jm26B9EF3mXT=wzqIKc%qfk!|6i`F0JtscH`hMzE~O?6C3L~@A>4jiF@OYr)~cEa+YxG8K-Hfg@uKJr=J#0`WWn0 zXd_p@b6p_E{ki83{jYcu4)kd{)TkdK%c{bsH5gR;UUr%HeB<3b`xx!>pCfd{(!WQu zwA{3=U6#-ze#+L~-u?dfboL{9V)0J*zZVu43%dsLtTS0&Fz2_T9OFZ83%UM{aqE+J y#`IO~i&dYizfkA&j=g*5zS+Bv{4@g6`Tnc?rrvXt^NvI~fViHnelF{r5}E*%OC+%X literal 0 HcmV?d00001 diff --git a/third_party/lib/src/svg/xml_parsers.dart b/third_party/lib/src/svg/xml_parsers.dart index cd0cc1fa52c6..7ae94990ef20 100644 --- a/third_party/lib/src/svg/xml_parsers.dart +++ b/third_party/lib/src/svg/xml_parsers.dart @@ -140,14 +140,16 @@ CircularIntervalList? parseDashArray( final List parts = rawDashArray!.split(RegExp(r'[ ,]+')); final List doubles = []; + bool atLeastOneNonZeroDash = false; for (final String part in parts) { final double dashOffset = parseDoubleWithUnits(part, fontSize: fontSize, xHeight: xHeight)!; if (dashOffset != 0) { - doubles.add(dashOffset); + atLeastOneNonZeroDash = true; } + doubles.add(dashOffset); } - if (doubles.isEmpty) { + if (doubles.isEmpty || !atLeastOneNonZeroDash) { return null; } return CircularIntervalList(doubles); From 20ac9f4c61b732456ac0a45eb52911a1d768e7f3 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 11 Jan 2022 15:38:57 -0800 Subject: [PATCH 426/512] Fix nested g in defs; sync*; v1.0.1 --- third_party/CHANGELOG.md | 4 +- .../example/assets/simple/group_in_defs.svg | 11 +++ third_party/golden/simple/group_in_defs.png | Bin 0 -> 1717 bytes third_party/lib/src/picture_provider.dart | 59 ++++++------ third_party/lib/src/svg/parser_state.dart | 90 +++++++++--------- third_party/pubspec.yaml | 2 +- 6 files changed, 89 insertions(+), 77 deletions(-) create mode 100644 third_party/example/assets/simple/group_in_defs.svg create mode 100644 third_party/golden/simple/group_in_defs.png diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 03875dfaa62f..9dfda1da17e6 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,11 +1,13 @@ # CHANGES -## UNRELEASED +## 1.0.1 - Fix bug with incorrect fills in some cases of `` elements. - Analysis cleanup of Dart code. - Fix bug where self-closing `` tags could alter rendering. - Fix bug where an invalid `@stroke-dasharray` could cause an infinite loop. +- Fix bugs related to nested `` elements in ``. +- Remove unnecessary `sync*` related code. ## 1.0.0 diff --git a/third_party/example/assets/simple/group_in_defs.svg b/third_party/example/assets/simple/group_in_defs.svg new file mode 100644 index 000000000000..243c4b3ea47d --- /dev/null +++ b/third_party/example/assets/simple/group_in_defs.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/third_party/golden/simple/group_in_defs.png b/third_party/golden/simple/group_in_defs.png new file mode 100644 index 0000000000000000000000000000000000000000..6a448570ed257ead006953f91be6d1918ad1c228 GIT binary patch literal 1717 zcmeHI`%}_c6h~JO-{vT$Yd~(Rl$wRws;epaWZTlovNTOd`4$n85^5zSTAQi))?6Q$ zR+y%^MyqC)r75oRm>u6z5a~imKG5==?zh>0V1L*j_s+TZGk4CNIp=)t=iGZU_+Ws6 zuB9#n0x`e``W^zY=j(*Sz_tDumkojj{ZPO@2v=nF0o-WO_u&u2!I1=yNrOOOQFve6 z;l#43H}crhK&xNW?X>Bqc&NWwvK{0I;l8G?&h(2K^!M54G7&Io$UQDY<6+ro28J*;nDed9wYJ; z08l02vc;jrXTMV^06;DYH}ymK<=!Ws0f1Pm<3%I{UmX+8kBby8FQTcEvGMV{Zc5Rn zwJ7i;TN!HF<%WEl0GOxIMMxB?o=Z`!UMUc#jW1d4XDja}!8Bt_ZgR*6FS08HAFHl{ zP{R3jMHS7lslc^zd8@0JAF3|(5=YK8^TZWiywI0HHa}(zGRg}{AF_sb7c@)O^n+^#1Je10|dx zXM@~2!F$$gsdVSwtRKiFV|{&n1D!9Rw^{=o`>@5Xf)h06_P)4D;@cE|y?eE_T@F1P zz7J%2?R$E+7STmblKL5;=%;??2-`4?8PaiR2(*{t5={L#t>{>8%E#Lx(ys2BA|tY%#IEE>$WJtgvlor9h60y#?qbV$bIg&7pqk#%04$u!>KNXaom?X7z^z%}7F zZpr4?+|Uri#AuqhI{YbDmC`z+-vHC@sO(Dkm@%twII+Au%6Cn9@f z@lo@au|sQbe3TA39^$F#Y0!pBHKhjnz6= zFzj7Twp?T6s#Fw;q{v%S`6YhQH4D_dthBtmm3uQ9>c8w6$X3R?T6K?nvbQqSMkwrd zj~Q_mR+%}f+$u~9ro~!1jNT~X)G(LlNP_H^V*9?t*OR@O>-oo(5ytHn_`Dc1irw1T zPu^9S@T6@tC+#5nu!;4OMq^R&)X70M3 z$W1a8&wEy!$YfF(k@Owr{T}9a;`vczoS7eyDlySMQEn6OfecDWNU(J({nUU-?^h?5 zT}mJTHbxT%`kkxo`*tGzi%8WRGG~3IxCTFjPN$1%Yq82Q=9d*lfw<+#lSU6QwOvNX zK*{l}wFguQ-QK66+ZG>}l~Rp*7bJAgL4i*SRl=58OPcCGGigj&#W+6i71*nobkU}J w2&z-tV9 { return; } FlutterError.reportError(FlutterErrorDetails( - exception: exception, - stack: stack, - library: 'SVG', - context: ErrorDescription('while resolving a picture'), - silent: true, // could be a network error or whatnot - informationCollector: () sync* { - yield DiagnosticsProperty( - 'Picture provider', this); - yield DiagnosticsProperty('Picture key', _lastKey, - defaultValue: null); - })); + exception: exception, + stack: stack, + library: 'SVG', + context: ErrorDescription('while resolving a picture'), + silent: true, // could be a network error or whatnot + informationCollector: () => [ + DiagnosticsProperty('Picture provider', this), + DiagnosticsProperty('Picture key', _lastKey, defaultValue: null), + ], + )); }); return stream; } @@ -526,11 +525,13 @@ abstract class AssetBundlePictureProvider @override PictureStreamCompleter load(AssetBundlePictureKey key, {PictureErrorListener? onError}) { - return OneFramePictureStreamCompleter(_loadAsync(key, onError), - informationCollector: () sync* { - yield DiagnosticsProperty('Picture provider', this); - yield DiagnosticsProperty('Picture key', key); - }); + return OneFramePictureStreamCompleter( + _loadAsync(key, onError), + informationCollector: () => [ + DiagnosticsProperty('Picture provider', this), + DiagnosticsProperty('Picture key', key), + ], + ); } /// Fetches the picture from the asset bundle, decodes it, and returns a @@ -623,14 +624,14 @@ class NetworkPicture @override PictureStreamCompleter load(PictureKey key, {PictureErrorListener? onError}) { - return OneFramePictureStreamCompleter(_loadAsync(key, onError: onError), - informationCollector: () sync* { - yield DiagnosticsProperty('Picture provider', this); - yield DiagnosticsProperty>( - 'Picture key', - key, - ); - }); + return OneFramePictureStreamCompleter( + _loadAsync(key, onError: onError), + informationCollector: () => [ + DiagnosticsProperty('Picture provider', this), + DiagnosticsProperty>( + 'Picture key', key), + ], + ); } Future _loadAsync(PictureKey key, @@ -690,10 +691,12 @@ class FilePicture extends PictureProvider, Uint8List> { @override PictureStreamCompleter load(PictureKey key, {PictureErrorListener? onError}) { - return OneFramePictureStreamCompleter(_loadAsync(key, onError: onError), - informationCollector: () sync* { - yield DiagnosticsProperty('Path', file.path); - }); + return OneFramePictureStreamCompleter( + _loadAsync(key, onError: onError), + informationCollector: () => [ + DiagnosticsProperty('Path', file.path), + ], + ); } Future _loadAsync(PictureKey key, diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index 283a1a32edba..651e7a152557 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -122,14 +122,13 @@ class _Elements { } FlutterError.reportError(FlutterErrorDetails( exception: UnsupportedError(errorMessage), - informationCollector: () sync* { - yield ErrorDescription( - 'The root element contained an unsupported nested SVG element.'); - if (parserState._key != null) { - yield ErrorDescription(''); - yield DiagnosticsProperty('Picture key', parserState._key); - } - }, + informationCollector: () => [ + ErrorDescription( + 'The root element contained an unsupported nested SVG element.'), + if (parserState._key != null) ErrorDescription(''), + if (parserState._key != null) + DiagnosticsProperty('Picture key', parserState._key), + ], library: 'SVG', context: ErrorDescription('in _Element.svg'), )); @@ -201,9 +200,7 @@ class _Elements { transform: parseTransform(parserState.attribute('transform'))?.storage, color: color, ); - if (!parserState._inDefs) { - parent.children!.add(group); - } + parent.children!.add(group); parserState.addGroup(parserState._currentStartElement!, group); return null; } @@ -276,11 +273,9 @@ class _Elements { style, transform: transform.storage, ); + parserState.checkForIri(group); - final bool isIri = parserState.checkForIri(group); - if (!parserState._inDefs || !isIri) { - parent.children!.add(group); - } + parent.children!.add(group); return null; } @@ -562,15 +557,13 @@ class _Elements { } FlutterError.reportError(FlutterErrorDetails( exception: UnsupportedError(errorMessage), - informationCollector: () sync* { - yield ErrorDescription( - 'The element contained an unsupported child ${event.name}'); - if (parserState._key != null) { - yield ErrorDescription(''); - yield DiagnosticsProperty( - 'Picture key', parserState._key); - } - }, + informationCollector: () => [ + ErrorDescription( + 'The element contained an unsupported child ${event.name}'), + if (parserState._key != null) ErrorDescription(''), + if (parserState._key != null) + DiagnosticsProperty('Picture key', parserState._key), + ], library: 'SVG', context: ErrorDescription('in _Element.clipPath'), )); @@ -633,10 +626,9 @@ class _Elements { size: size, transform: parseTransform(parserState.attribute('transform'))?.storage, ); - final bool isIri = parserState.checkForIri(drawable); - if (!parserState._inDefs || !isIri) { - parserState.currentGroup!.children!.add(drawable); - } + parserState.checkForIri(drawable); + + parserState.currentGroup!.children!.add(drawable); } static Future text( @@ -933,7 +925,6 @@ class SvgParserState { final DrawableDefinitionServer _definitions = DrawableDefinitionServer(); final Queue<_SvgGroupTuple> _parentDrawables = ListQueue<_SvgGroupTuple>(10); DrawableRoot? _root; - bool _inDefs = false; late Map _currentAttributes; XmlStartElementEvent? _currentStartElement; @@ -1090,19 +1081,27 @@ class SvgParserState { ), transform: parseTransform(getAttribute(attributes, 'transform'))?.storage, ); - final bool isIri = checkForIri(drawable); - if (!_inDefs || !isIri) { - parent.children!.add(drawable); - } + checkForIri(drawable); + parent.children!.add(drawable); return true; } /// Potentially handles a starting element. bool startElement(XmlStartElementEvent event) { if (event.name == 'defs') { - // we won't get a call to `endElement()` if we're in a '' - _inDefs = !event.isSelfClosing; - return true; + if (!event.isSelfClosing) { + addGroup( + event, + DrawableGroup( + '__defs__${event.hashCode}', + [], + null, + color: currentGroup?.color, + transform: currentGroup?.transform, + ), + ); + return true; + } } return addShape(event); } @@ -1112,9 +1111,6 @@ class SvgParserState { if (event.name == _parentDrawables.last.name) { _parentDrawables.removeLast(); } - if (event.name == 'defs') { - _inDefs = false; - } } /// Prints an error for unhandled elements. @@ -1132,17 +1128,17 @@ class SvgParserState { FlutterError.reportError(FlutterErrorDetails( exception: UnimplementedError( 'The w6zG~W4O+^ z>i?NY?oXf^Puc~+fDM$VgRNBpOZj{2cMP~gCqWAX4 z7>%$ux8@a&_B(pt``KSt;r+sR-$N;jdpY>|pyvPiN)9ohd*>mVST3wMo)){`B(&eX z1?zZJ-4u9NZ|~j1rdZYq4R$?swf}<6(#ex%7r{kh%U@kT)&kWuAszS%oJts=*OcL9 zaZwK<5DZw%1IFHXgFplP6JiL^dk8+SgM$D?8X+gE4172hXh!WeqIO>}$I9?Nry$*S zQ#f)RuH{P7RwA3v9f<-w>{PSzom;>(i&^l{E0(&Xp4A-*q-@{W1oE3K;1zb{&n28dSC2$N+6auXe0}e4b z)KLJ?5c*>@9K#I^)W;uU_Z`enquTUxr>mNq z1{0_puF-M7j${rs!dxxo3EelGodF1TvjV;Zpo;s{5f1pyCuRp=HDZ?s#IA4f?h|-p zGd|Mq^4hDa@Bh!c4ZE?O&x&XZ_ptZGYK4$9F4~{%R!}G1leCBx`dtNUS|K zL-7J5s4W@%mhXg1!}a4PD%!t&Qn%f_oquRajn3@C*)`o&K9o7V6DwzVMEhjVdDJ1fjhr#@=lp#@4EBqi=CCQ>73>R(>QKPNM&_Jpe5G`n4wegeC`FYEPJ{|vwS>$-`fuRSp3927qOv|NC3T3G-0 zA{K`|+tQy1yqE$ShWt8ny&5~)%ITb@^+x$w0)f&om;P8B)@}=Wzy59BwUfZ1vqw87 za2lB8J(&*l#(V}Id8SyQ0C(2amzkz3EqG&Ed0Jq1)$|&>4_|NIe=5|n=3?siFV0fI z{As5DLW^gs|B-b4C;Hd(SM-S~GQhzb>HgF2|2Usww0nL^;x@1eaB)=+Clj+$fF@H( z-fqP??~QMT$KI-#m;QC*&6vkp&8699G3)Bq0*kFZXINw=b9OVaed(3(3kS|IZ)CM? zJdnW&%t8MveBuK21uiYj)_a{Fnw0OErMzMN?d$QoPwkhOwcP&p+t>P)4tHlYw-pPN z^oJ=uc$Sl>pv@fZH~ZqxSvdhF@F1s=oZawpr^-#l{IIOGG=T%QXjtwPhIg-F@k@uIlr?J->Ia zpEUQ*=4g|XYn4Gez&aHr*;t$u3oODPmc2Ku)2Og|xjc%w;q!Zz+zY)*3{7V8bK4;& zYV82FZ+8?v)`J|G1w4I0fWdKg|2b#iaazCv;|?(W-q}$o&Y}Q5d@BRk^jL7#{kbCK zSgkyu;=DV+or2)AxCBgq-nj5=@n^`%T#V+xBGEkW4lCqrE)LMv#f;AvD__cQ@Eg3`~x| zW+h9mofSXCq5|M)9|ez(#X?-sxB%Go8};sJ?2abp(Y!lyi>k)|{M*Z$c{e1-K4ky` MPgg&ebxsLQ025IeI{*Lx literal 0 HcmV?d00001 From 2b0e9f22fe84a14fa9e173f0c5f8774e4aeaf91d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 23 May 2022 09:21:49 -0700 Subject: [PATCH 442/512] remove stale files --- .../android/gradle/wrapper/gradle-wrapper.jar | Bin 53636 -> 0 bytes third_party/example/android/gradlew | 160 ------------------ third_party/example/android/gradlew.bat | 90 ---------- third_party/pubspec.yaml | 2 +- 4 files changed, 1 insertion(+), 251 deletions(-) delete mode 100644 third_party/example/android/gradle/wrapper/gradle-wrapper.jar delete mode 100755 third_party/example/android/gradlew delete mode 100644 third_party/example/android/gradlew.bat diff --git a/third_party/example/android/gradle/wrapper/gradle-wrapper.jar b/third_party/example/android/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 13372aef5e24af05341d49695ee84e5f9b594659..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53636 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ⅅ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 H-+%o-(+5aQ diff --git a/third_party/example/android/gradlew b/third_party/example/android/gradlew deleted file mode 100755 index 9d82f7891513..000000000000 --- a/third_party/example/android/gradlew +++ /dev/null @@ -1,160 +0,0 @@ -#!/usr/bin/env bash - -############################################################################## -## -## Gradle start up script for UN*X -## -############################################################################## - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" - -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` - -# Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" - -warn ( ) { - echo "$*" -} - -die ( ) { - echo - echo "$*" - echo - exit 1 -} - -# OS specific support (must be 'true' or 'false'). -cygwin=false -msys=false -darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; -esac - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null - -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar - -# Determine the Java command to use to start the JVM. -if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - if [ ! -x "$JAVACMD" ] ; then - die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." - fi -else - JAVACMD="java" - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. - -Please set the JAVA_HOME variable in your environment to match the -location of your Java installation." -fi - -# Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi -fi - -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi - -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi - # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" - fi - i=$((i+1)) - done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac -fi - -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" - -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/third_party/example/android/gradlew.bat b/third_party/example/android/gradlew.bat deleted file mode 100644 index aec99730b4e8..000000000000 --- a/third_party/example/android/gradlew.bat +++ /dev/null @@ -1,90 +0,0 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 2a161fa4ae40..e6df26dd60ed 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -20,7 +20,7 @@ dev_dependencies: environment: sdk: '>=2.17.0-0 <3.0.0' - flutter: ">=2.11.0-0.1.pre <3.0.0" + flutter: ">=2.11.0-0.1.pre" ## For developing features that require new functionality in engine: # dependency_overrides: From 2198e41a2215291cef37099eb1ac3a0bb5355714 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 17 Jun 2022 14:37:39 -0700 Subject: [PATCH 443/512] update goldens for fractional translation (#721) Co-authored-by: Jonah --- .../test/golden_widget/columns_and_rows.png | Bin 23184 -> 25764 bytes .../test/golden_widget/flutter_logo.asset.png | Bin 10130 -> 10330 bytes .../golden_widget/flutter_logo.memory.png | Bin 10130 -> 10330 bytes .../golden_widget/flutter_logo.network.png | Bin 10130 -> 10330 bytes ...go.string.color_filter.blendmode_color.png | Bin 9032 -> 9168 bytes .../flutter_logo.string.color_filter.png | Bin 7518 -> 7618 bytes .../golden_widget/flutter_logo.string.ltr.png | Bin 3411 -> 3404 bytes .../golden_widget/flutter_logo.string.png | Bin 10130 -> 10330 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 3496 -> 3490 bytes 9 files changed, 0 insertions(+), 0 deletions(-) diff --git a/third_party/test/golden_widget/columns_and_rows.png b/third_party/test/golden_widget/columns_and_rows.png index 34053145e281c2d6bf83eb6acc305fd547a1555f..d4baaddf86b636c9e296dce515657b0d4ff1654e 100644 GIT binary patch literal 25764 zcmbq*2UJu`v+f`QDgvS;0U45_0wNj7Dl%jQlqeucB!lEMpeUdSLy#<>WR#pUl0lL% z63CU(Q-TkbH6ud|b}yd&6L~FiEldPaHlk4#`?l z8zN`+w4Z*J5`Rq%dq~nvn{umT{4s9x^9+_`?wt1fer0$W`?p(ZQhFn8x9gT=+3B?H zcw^nR?Q0Mcl_`4L8p=y}bEFBIo&qcM7E6jEPc=Vd3&* z7m}NqVwy2XdWxYc{O~Qoy*BNmjXYYI`%@2r41z!{PX)>W?7R}}G+w;^Il|7~VeP^C zwDSI;Y7uQ#Y4Yh06^ASPruR9g-Y6U6JZ-}1GQ`g(I~2RnQ(^6lg+;5^JA206Af20* zs_j7Cf^gHJBxCDEW@XruJeIW155;#iI;GOSOuZX#uh1tZI0x&k6(@(WSbxP*bMEfx zf1#~yx=nAv=cmXjz4DpWXvL95Mu?-?=^#Ju3|fFD)Q9*Cv)NEbWW zN_D;BI==CDt5~QNYQ^pWTTy?C#LoP%@03yQu9Q;&@sYy_G&0TaVjXXPxx?HwO>MA# zWJ^-{$1U&dzEIeo$1onhp}H-!lAYS5F};GY)&6@hk?~kYrbL@-Lw;*WFad#uHGT8I z1naiF5PO~)8w-g%7FU}z4uvZZAQ@N-VS-7#S7Mr5LeE?=AcgesJdJP`56w!2@cq<$UI1z zlt!hWbiGI-yfQfPvzHKw)0h1w>=yqsOg6a#}b z#(^ELe|xRcLRNa`4r8XM-@z2sG-A^;>i!uRqYv0wYQ5rsVvV0|=ybpD8;89%u6mrM zx30lP$tW+uEE|>xHWUt=w@fQ$^b`e1Hxi71(3o3TikyQLzJ(gMgXP?-9(BbZVR^AZ zFr(niG2i>=`skzd~C#Hp{s#xkvl+E*wok;zS{D3_tX1u03IaSwfq` z_q?nR99WT6+h_+{!KgsT=58Kv;Bo88Vb9^v@1tn#NO)0+E&uCxl0|9g;oiOQI*QZZ z7){Hr3i6MzN@|xy|2kvvLnQ+*=7RyHAIcZK%m=TdiWScrXBx=

t*%$@hS!C00^JF1i0X6&Mk*F7tCFiuKoiJG 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�u9vbX{zc#lGCFlb@L2Onwq@UnkgLn5^=% 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 OceTRWk)O+RKm31$8ZSuz literal 10130 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 diff --git a/third_party/test/golden_widget/flutter_logo.memory.png b/third_party/test/golden_widget/flutter_logo.memory.png index fc9ffa27529c1c7d62c7faecff5822448e6a262e..7b88eeff0280f9170d14a57356ba73fe922ededb 100644 GIT binary patch literal 10330 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 OceTRWk)O+RKm31$8ZSuz literal 10130 zcmcI~i$7HB_y3+TW$R`SLZ#+HqLU(&#F(aGCf@iXCgCbEXVYQxc# z?#6!;ymklI%i8<9tZfV5T8mmxy2i#>_e_;jI*$&YplVQWY&-Xtec{4M^-8+uHtc9q zw*AgoJO9cb4NU#O670AA519u1K%NLWyXkjs5>=;rs-g3?Of=)~o`4+{{SHT*1|8f} z{j0uMylB_XHL0z==fBJT^S$Qa{rVJO^?&&%e%&8TL0;Zi9@4hEIR05@^FZ)i!;Ce> zgCz%={9KzaQ1)R=WP`mBJ1bB3qtZkRqm+3nj1627;yhQj%C;rK4#kk0Y!13c=uD?j zxu&IxtSIG$+FT?nT+Y;ytvW$Nkup_=Scj99h)~kKTOuT-iZfN2h#Coc2te5cD3gom z#o>J@`tt$lR|3fle|wU6YYa%%7>@J-rBF*g5S{WR2*u+iq3UKQLJZvqd@XwrfgG4h zu?5kL5O488)FVX)5H(5B8bp*79YqM1N*J3%XCh)<+^v#lVE0$j*i7I>!tTXYV+qyG z5CI+?=f#`@?Ifz#d@h2n!ow!&g8q+*2&B&hXLk@#FK2`50fM*pIf#n}L7-r*2zj{z zkE?THzJBv`VQV0*rRG7$2GA;m`?m{9tiI5Gp1kyqj z6a7UZO{Y+u>4aN1Ap#4@xE`jV+(`tJECAIbLF)i?5((-Hpw0y71^`tfKoMM%oDE$N zph<+&B7M-r2u(u)XmWA$h&rq%g$4KsBKE+9LV$`qK@1~;B2vZQlHyGKEr~T#3Eq;T zDgKsN2O?AaEh$ciw;u@F9;>M|rXk^0eKD$r=J# z1p*a?mA)6|1q3-9oY_kDFQK6&CkZZ0GYU1IB%q0as7v(HguNtxGAUvpvPn@BL@FsV zDOA4+Q4hpv7YppF5vqET2&JAJ@e{zCn7POl9j@pz z8LcZc)Y+8OyogY4&L`%^2~{Td92r6?m6k=$tqpL3Y$PW^G>WCqCc@%8i$dK%>@>(i z0Bs>buK}nD0h$G%(In_O0F5U=!T&@75h`1KB`lqs4J8x`RgG9~$VC=c#3md;1Ssb5 zmFOgbz1+~7Fk0e5rD-lA@ISbL2pc`@Ss(ZyY7wHxd=N?hJ$8afM$N+jL>j5Ek4i(G z2nzKOARe&}kY&1DQ9fxb7sc@N17JP&fGWwh93pUq_bOFp36C7c4@%evl;n+4X%|UeYO6(vBB^>6cwf`uz#f9A!5-EUaj{g98&5+w zkRIxtN5Y~>d}~#vvp$J*luBC&ePD;%uu8<;Nh0~8SXLzAmNT59=g7F;)aIsBNw?3@ zP&E=X3qZq3(2W49M}i)w(x#B0aDb?hv%w<`G)bo&=uBtQ5zz|JBxggu2nh=#Czcye zR3ailwN{HtxTKiE6_p^Qcnic566=;N=uU{MKzBl11G=QRmn-7>5wwvxDol(VtrB$_ zN+Z`ILf-F^KVj?0e+^ICQ-+`Do>9BZ?lg_?m zQ>d22l1IFgkg$0qfdC*NB>~LY-1OBXm$@p;m*jCKidDioCSa9mXu$;R0xE6G1gtiN zYCytv0IWI*O9QgTBv~d6^&(ZVNF>aGv=vTgO2SC8Tq^B<6YYsen88GUU9QIjmnTYC zJxQPhK{2-kqE`tQ#0XLpff!GUB_I;8@nx4d!{3+O*z;!0vH1<9_L<|ucjL{8pEopX zAk{=XH$Upkcro7F)6=7voLDs&Y+z_DbT-julDo3@=?J-IT$y70`_YmEjbFbE7opw> zNZ5RwecYl_#Z^(tH zxmiT!OWLMPMX{U2ye5s6s8Ge^X1_U7Ib4O|H;uxp{!e$aFyso64GYv;BGOA0VS+mo z`{{)BO(vg5s0bk5#TYPeJ*L}m_0F%uo?;9VFJBk%_$Xwq6VDV1PX^EQAI~fbZzdnT z{Ih)$g=Y%SKilVnJA4#URIso=@imPQ+3H5|9n{Vo8h~&qN`& ztDvD9Ratu-g`~Uq@~DGnhab=OFckEslS?PuD}Y7Ip+EiW=d**TM2-G5>c=xInG!Af zQ2jH>^rg%n-h`_%CGqGiCHDsfy9%bqa z3p8qbdRCSxK8aM;gP^2FN*sPP9H~kfx+gpOJyvFBSwHx#gd?L&S~_X!@m=Px)j>y5 z7GLx40AslGXbR`GN$0o6J2daBGMpiYqeM!kgJtznsTjTD)S@s2qKDG&PL{=&8Oe-T zyp9OD=&2Hh^2N8fLa#eKp+hA0P=}KanOHcTC507oi_TDGix)>KXMrOkemS*8`}Fh{ zPoDUtu8cC1&cqVYBsS-6J)5J;NB3b2JV^_SlIU=jKF9E$DW!@VY~c{uD1eZ&J#hnv zKue!ORdC)Z25ws-<6t%}12ve(+zm5XU_iYU4CE`xD3He)GB@&}>(vPPMT~W8wGg4w zPG0XoVg3YY;s!QGD#O9e^^ioL!DR8)%D7u*v2p~mbj_@*Y`)N|ny{))XOzH2P+=1v zw@Sq$@@ujjiN%4Ztl-R>Ql_fUZ$U81)2Bt_;EbN^}&$y^-mh<&0a<^n;K{ zmPRS#8RHanHV?*g5>8J4v>bV@%T4!tY=gT`klTqdN^Bq}Nxy*muZENJsxMW{hYQEK z4iloQ6uQoWq1kIK;#!+W;eJiR37@nU!gZJFoU}MB2XJB;ThwsFveC@RyT0JK|}Lj&9Ume*KDglUv|e* z79WE?$5ru5l`5klN@7u}`117Sq9sVWS4+msH>Qrm*JNhFw|#01g54`1HA-I&x3>8$ z85`MN{w)f4A;CLL-XTUer^%7y3%HQ9FfOaGa#R^yNE(^ivg)byLrY~8F_bKp(ix9c zSbs+;<9RM53+O7b)_jf#?*Ap{O9guDHi;bJk+(Az33=1>?5UuIyS6TBpPg;l{2rY!SE?MYr)maNoY8q=wu7`v}CzQ7>b+v z4Q^FiS|U9AXR%ro^uVv1IvlrE47{lYn#@}wOat(yEV!XV`K+F+fj2=mg5T;43W%m? zXkv28(_>&-bD=EZY$01^vjX>cqY9G?XT3o=9fvqiT=2ZBm*EgM0Ub(IGxnO zBsQFH$Vt{Ut<*EszqV^|=tyx(<(Dyy(QR|Ni>NfcSoDhhX#pqsadGlGJJ4~oyAkMq z^hM=?kT{fb6A;)@*u$^y6XH1Xw$US%F~ZEp9hxyNwGIN?gyjB~p#33zBTaQL>Zqk~ z`}!>kd)xp1$h_^GZr=dSc|kHGyKJ8UtFfA(14Z4V#qVl&D&Q42YgJak#|H=8Lprjx zwHc1S$-397clen&`WyDf>r&3@(hqe9FE9Q_;Y(NhXUZ^K&sw6eL&tmGU0@vlTw^)z z@#%?fcbu@osc?2>nN;uEtIUJGE_Q`qLa(6|{Gz`Qj*O!Nq;{jftXeDfXy!WKnjKya zPK9rSnwkubEaB){)r`0gy;dH**Hfe*8iOI9%@*&o7|A`wczCGuc7xpP?z@ftX1#Y9 z>{@Nc`j7F?64HJXepBAB!s1%P_{^j~)m48c9ZQb0F5KSjSZL>CZvM>pzzg4Jg`s}6 zdCg-hw+ojb!BAE>%t!yNKOOf%YjdB`{G`h9cwLCwT}Y?@vYSkUFU zwKW_F>Hhdj+DJun+A+UFk`M1!FcRqTqYE6%q~_qPyKc9jJg>R4*ghR!xvA){Z|}<8 z3O-m=GL~L^?bdhjY-8iQB~7|KQ7=@sba?fBUCWCHzMivBOO1(prR8wPcScjHSgOOR zx$Do_bxVtp@M1q7b)E-xAt&*x?uKIdUw=Be55Ia}E^Sh3_X&A2)OIE=S3M*=Rn_qp^V>m4n0Tk0-8D;xJN(DaW4}7GdASon$UPV zIjQls?$(|vi0ovWA|KbkOY@tVkou?9n!uSS@s$g*Y#A_d+%xUOa)CSu-pR8 zk4br##-TWr>zkvpk9M}<{_!8tH9O7d&ar+?l5_}+ibNo!^A zL2Pa<{j5v!`^DO2(kHGnStW3Z6q&-|J>2=G*srTx`s8VE=cM+8bZ?pD$u@9T2i$dJ zd%1-SmySP#;FM`Id`!%RL7yMRHN?jy%$U`+9M9DZ)j&^y?WGygTRJXm`zst`sJ|&l zo4Ek?1T{-Sg$63C**gDAvyipNZF?}Tns+HU;O?i474N%!ceQ!;7Gz_aXEThVFs3<7 zhDmglTBmsOW@(JV3ogD8nx$oKj*%R~Rv zgoZYLZxvJxUTo-Icn#L+{wG6*kr;C!eyE~RAEj}NBja={`O*qr-!9+ex+(2K{?@*O zDs(CzCc#oVYjjwap=<#_(zs^=bBjjdq1OWc{O%sFRl{u?`VJ8`t081(__kId-#Zj= zKU$?r%$l2Beox{wTFkYvjlvToku6?-WoK@+D*8SoNGtl{X|JC0BGs4U-|@l0&!O0A zPY0o<2WnIKw#!2ThWg?-!JWmUjST|j7ei(iUVgrRZM?U)tu@Pquu2E3=OZP7qa7dZ zL33OhTPp1;$jQzPtgXIhdH#gJ?$3s9-|cK#$0f)+;!z*z4q-)%&}9AA?(5ctI~-G& z&t(UtnZ3#lTt1&C;y~QaM@b%q^nV=%v}Qqji>JA{x&v&1HLo@mj(l-dXS9y$?{0mS zX)^CLmJXjv;Nqea$KV8vXE;?#rB@qopI>Zd<&)FcTfvvcD@SALL7=0}_F8Er>?jiC zy&qg45O6+eoL^$up3#*XxO=YZ+&(@^l(Sj%yGe|Y?j~vKSeGF7_K@wVjCsaWD=+Pw zT6JOcV+letxa2D`SH zWi@=Mk0q6=R~tErk-1PSw!~ODLr+}49P7${5#qIsqr3j5O@eCWgD-K zhl%u3n|`-mx#;*CPp9C4;(1Ad_w|-0n^<*!?g;NYwz|ICce$z05evIF&ocHu^-M-7 zMA=`Lw<~!3m$YMD&x5QU!A|TQO7rr)Gt}=btysb6EPpp*wRz8*qTI#;4J}vcjhdd2 zqy08w!~lGOOP6Ky_+Pu{1$}NBijNx&HMzGwCwZuIQ?25R#YurPjX2MI5^u*Gsi~87 z2JCy35UAalY>mDQ=jI(k4(C|%#(MuwJO2H7(3reDybt!Y*jwK&TI@UL<9e{gGiAVL z#g5r&YnH?~-Pq%^;MKQEj75CLkZjRz3vwT8YjtWIk%qRHE8>T6m!32pU19d|yK|{( z)!^0Efa3>++u`4`?e;fXY@`-+suwJx@N5HK(cm>mJ6>4|T0M9Do|BZlDPi?wjqylq zj%urkooj7pe~Wy$|EYXur?0tXO2@?oJiN%q<=*F)4;J-DNz)#+7gv-?y@DDWPJD7q zUSyVL(cR|b8k{@yM{?D5jhgA5LjkLg>tBw!f7^2on^vAKapjA86X&s-M_U%m3+?S0 zlG`fQ=FF%Xax?ko=8DG)d!pav;o|P=m#d0GZtzjO?1;H# z(|a42jCHm;H3dtb#>XX3 z;QoW#=kkor*tB{PLeY%8A}Bvn{8hG~DELixXwaDKc|lHr-`l#YlRo{ep3;8*UCNpz zJ&!C#zrR|NsS&u}&h^rT=|>cEmH}T!*oC<#XR}VXdIlaGs!pi9k-FTtx4J33?{UW; z`q0Cmb7+02!S=b^)1K`=w?LIuGW+|w870VL*`F^S8(jMoTa@QHvrlH!@Z0aRx-+Z2 z6O(r>FkL^sR`E;RKS4@C|4cFzKe?Xh(($7YgZx232%Z~;u>rQ=Ww0-4aR(I?o z_JMQp*auCB(Fe9o`CYkf_L@rXL>uYa!naA6LQI#J`Nkk?DzgiMhItPIhyU?8(tdJB zh`~+RQQ?};rLe8b@5ri6jJ25wp*Nn77(cnAp*K~)QI8395J;0w`waG%6$E|eEh(Pd z1%ZXSNIFJmw`IyNo)KwnKUy?CuuZgR?vNYCY`vFfSGapeYM_&QSL@c@v*^?c*b63g z8uK}ehQ_)eMUq*Jd5>jsleP#;ZVTay6@qAorASW zefrx&?PsS2@3dPPm_K_FoeJNzoo_8>do@C$6Ui|*@AeIOa?Jk|Z+5fa9=j!ln*$R0 zV(vGH!jrdWB#tefU%pg7g;?pC-pF&ReDEgo)5)#1@>k#XZCgf<#IoROr?+hm{jQHN zGcneo(06T`edU9#F8)0SGCx(sz-7jNc*O}7ma{?LS7c`SEY`bHX_M3@yJ5wpz{QW2 z#Z(n9yLRv1?!%FB(ExVV^_a-6EmD$e!?D?2)A2pmr~Q4dPe9M>M3;nT{#M2EED0L+ z`RFyptny{_yVc=+musQ5&S$rk#Q@dw%PIK>5gK;$=zYbk3SIi${lc!4!uj1Pp@-i- zklhb@*KyrO=m)!7-PdSk=PQTVUUhQK%Z2kVn-6|AF%RA28(7t4xki{jgHGM}^`^3O z_C|a}H7`HDxOV&ZYbNI7pH1GbfV}^MmkwW;PoY!G`u=Mu<^2 z7>rq)c4=kVHX$S`VONiRQ_OmQ6-|nZgJ}2!jG2N*?oJuT?E_AW8Bxk_wR!1oJqS|4 zFW2EDuU}%H@o(s_2OOmhQ-i9FW=APMgm&8=Dw3Hvz-}8+4jpq39cgkZ+8;3XI%56v z^|g`8!=Pc-LqoL826KwXZ_DJLgOulC3_g>WuD3GS9YGF0I{Hsd#O_d8u9dCNAlRf1 zNq3KbvN|?gb|APnzGw-pK6ND(5u}Wqg8nA+id}_RbUdaPUPwizUJm**bhvSyaR___ zP@_{L+N+Qf7mcR=)FanTLW;?EpL&pzJBuH6J|2HGD~1ENXlrqa$Ai^~-_@zV2Y)@1 zEbC!JEA!|qL)#t|j;><^(c^|VOtwmsO`H5=yMibtrMSE5_ZzR? zhx8g>feX-6sPpXY`o49nW1o*jQO1{lMYGs6;&&U?V(cs$hX3jUN=0HF9{v*#t~y&R z;iK>^5-GPK+MS_&a}>r?VPQ~aVXma}Y@t6CK?-<8dlUQyWs5csT_fhgXHO(o1&6{* zM(~Lg@AYyjpf2E}P~Yi*PvhyvgaQ0(>PvkB%N%TVq@XMvI`uNZ_LH!$0rofvn**>= zMZ#fC0k(;RodU2ZfdyZA5p*>{<`$@4iNwuHVt}j`Vc;&HLT6xD@*3KICHm*%Ki=^s z`tOA+3YJO`z<=j6Eu0YdK-{LCBt`sfG$BGw5}6iDiul{Jgt!1INz={~q7)aC3DF*0 znCwLGIstaAG28|G$4XoyA{_8l9nm9U6`{S1P7DH+X%W3d0sx#nM3CJ8^#f-U+!=8+ zfJQICox#h)T=?VyfrSD9l0|Uk?F6Ka1X31U7}Mbs3k>Huh`@$5IFl=|Ig5M=P&FLX il!y@WfBZMxJ5Fhu`EUSvIOhv)YK`?;{%xK|`2PcsaC$QU diff --git a/third_party/test/golden_widget/flutter_logo.network.png b/third_party/test/golden_widget/flutter_logo.network.png index fc9ffa27529c1c7d62c7faecff5822448e6a262e..7b88eeff0280f9170d14a57356ba73fe922ededb 100644 GIT binary patch literal 10330 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 OceTRWk)O+RKm31$8ZSuz literal 10130 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 diff --git a/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png b/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png index d46b6ded9b7b4cbe558dcf475ae18bbc7c50b096..6b12ded3f96226de0bef22a1502715fdd3b1c757 100644 GIT binary patch literal 9168 zcmcJV`#+TF|HrQxQ*PVAJ+!4#bD-$3!dlv5j4?tbYTJ|&rGup7qS9bwRwFq@spQa> zw5x+u+a{q8Idl{yDk&;NF-&2kzVG|G@6Y4A|G>vDJ-V;=`*ppq_jO&*>ohSQi=0P& zH{m;k&?r|I=@Nvr_z1C=6T{)l@sNGn;UCs-OPnR>!UMy0_z&kdiR)4V{$#{DB|?1U zDs@=8`^1OF=dtS>!s=DOre1jeXVIelN^ZH)_>F;nF>*b^IN#VKFYd5?S;RuVKz9$h zhX^-c*bzR-d$RhBvxTl8Mqk1g?r{lRcg8u#thV;Ip6Z*q?&)*-E`NSme6_As%k9aD zC8gs}dKG_q@@#Kr3Pkb0`wQ7&{&}KYB(uwIukT`^&!1912P|#d-D!i6U%_v!i!{yS zijPjV3$^;ZGIBFd*6pBqJ1gQ?O>e7T@%NPbY399Aw*Q*%pvh)3Q52HWbU2^n+{z)*_=I*csTX8TxIV5e{}H)HM@Vpmdg_ zJR4lT7W$x*?t_28e=ZJ-Zw;|5qD>)yyq~b?9ljXV(}{fxs(}k}yYeBi)Kc4q4%BPL=~!y5b;5R&;_w2vQ!6YpNd0VpkKm zDbHYxOu(Z-oCczAv8X?Yo~1>%faqZ?idbxBw7R&;(Nbrs&1eo(B*Yb&L+h4G@W*#L zr2IQvQHc=Bx8w4>gNS8HYn~H|(RWj*M4=9diH#FgG8L*{gRA%b1-$sQ*C?o!j9<rQAN z3&$$vafp&i96;7AHpdsHGR*dB6BgTC52vav4Y3R&vFb?3>PXz{C>k0w9Csyhgjlrb zx=un0XxS12sP-Yn|p)oUPfhrKtqrK*U7j60&=yi{7tQU0Rc)DDl#qOpj#^ZT%WUO*n*sOIn z39*jTy>(TOFRrCS*}&%b)0BA(z@aHCA4`x7Wvjnqv1!U8FQJ&Btavkrped{6527?> z(RmQ1DVw#P&7mpFx&op!Wf6y9#_g*qEH+J9v>Sj*QxbJql+F7Yyf9@^eLP~(ltqC64w|y)2A9uJw&Wv+U?`i% zW3g$r1K>?l7NtO}G-XjR$!91lw&M^qWzktsWhg5S;}Dp# z=&`Gup{zVqhh!-0VZ&n6ltu4N#0+J{6FCG;S>(STMbeZ-Tey6NvRQU)4oz8f1w?7e z%0qNWhO*TVDMMM3&x}@i3Ws1Qn`IWvdDUhn4v6s4z<#hm2c4@8OoNJaR`R8c{5mSnzE?VQO-~n4eIe3 z%8Ey`IW%QarIVbYEc#i8WGKsrq|rD;Y6m$(S)>t)8OowCJw8KOd65puP_~5R5DaB~ zP1ziVvgXDtHceS%a2!Q4vIiaH3}sO{WP_$G^3&rpl$Br7AsNbwIcyG1S)_z)(3C|< z1j$gAKY_)jDT}1WVurG4u@1>lR=keQVJJ(cqez;vC`Bx1D2wI`#0+K86fU2kth~lB zVQ6?3hvKBODD&Hw)}e6yJH4$BYX`fEGY>Uwn+|o2qE-Z>%vrM6BicV)YnnW`rQ~Ys z!_2{5#{# zQtS2`*hkHi$0N-=Ip`H9Fzg8Xa4Z1bsfo_dFcn26722yPibS3z+1zOPR} zCv~ESIntT2aQBU1D>fKR80kO@7)IK12saDcw&eaw*cinPum%Y7xSz6Gn-=^{t4EJ- zRb?(PVJcwv=<}`adI2PO=uzEgD^74n1owTkb>$q|pVun^%x)xpajcqLB;aCG2SKWm@1|pSdlIy})4p zX=Bk&*xvc2@83a?%WrKDNTXZuX;Qfnj7P`6+?sLc*98OlBS#r5+rq^WUCJm0QU_L6 z2Sm{h!G>!|e%`Rs+^vkmHl-uXh>@4(&|`7=H3958=bGPp&ve4gXjm0GD?M`mD=-0e z;Cb4m=K~pmjj%wJWQ@FS$q1whfRf`4Le?`8Om>vPM7B`hp?leHQnV$^;mYnd-Bkb>0xjwLjt?^k!96}(M%4;yyuI3#nBs!nJi~|=mM;Mlnyf8)Tn^% zyg}reIy+^_{LF!S8>Pgl%Oc554sq~aVq;u?jFuX}3ae+)&w@|siwdM7B~&Qni%tL`tq$Ub*co3M+?b^5T}&Sy1QOVSk40j!lq7Q<`h^uU_;idB-8foT(F- ziF(FcQf>YplA{uSI;{pq+GK2C#=r?+HZSU}CKrCC?j%o6p)7(gOx&eYTy z`R-ahBy`8x}P45Y^20 zV}l!6FxEXz`lqo}N$xRJLV^$c{Sv8QL$EZ(EwaBd=M99JSRh@oQ4Yt-v-S09T3|T} zTN>;QW8HzZd#B$PJ?OKaZbL;WZZb4T@~h=1ZAL&n6I!62J84R zGuLu7e1RSKwCwvflc>3MDT5e)q#s4|#q!M^);#Bo>0@aM%ET`ZCa~{yNz8 zymLJT3c(&Qrw(Epn~m(b`8*ZtAjGD2k*S>(o%3YK4-SNOT;7nr;5p<9whCF=&3?0m z>waw3g53gIH&qmEB3Y)-6C1NRd?S^`WN!Y^eng$jpjuT-Vp^Ft31^c^v8+rWS*^zt zFU2P{ql`KusSG8-vCK}H@Q+sO*UBi`r3b0MH=Xp@zLEOEgFD)3x5XxXV8 zwhqptB&LexunExQZ>A)I@o6t>+jFXjh9)K%ry-l*IS@`gc%SDWsf~y5;#Z zsUkNhithIf?1j+LRyfeXu4-`*cV~FGnFx{s{}=ULe;7A3_SLhM+io5X|CH;Kt!w{f zd*?Ma31_;$x?k??%5M7d&c?5Jl#8dQXM3ytw><>~1@pHRs^-nHwF+QuSn+-2beZ~* zvrzFUShXWOJbdUl!TP7_0I}3jVSdI;G&Q*@?y2tR(KQVX#|YN$+X2K~kW-a4!8_N;p#5_Ja)%kCaygDr|Rm^CuY^9#k)4!E!4;4CQUjexEZE zQnpq&_qDdQnc9V_T@=U-8g^Amgn5nS?ccwDftGQ$u|y8{GFbsag=prD&H!&&P!o^G z%c)4<#gbXBkdzEUkdvF6tFF!b8r0g~Hd}|~1*graz;vkL$$HOe*((=Y@ObGhEq+|K z6&$_plY&ma6|#F3j(ukv-A?_-m8gcDvz3z~FZS-;yH`zkjeXM^!@sL5Y!3=;$#f#B zVHjIcKsOUDYwWey``%(A7cV#nu2jXzQX;MX%^SZ*Ztw0c621EwsyBu~5koFpF_zbB zV%Tew(KP{>!^YPI`huDH(?##P29^iw)LoDg9zTM%yTW{P?OxH&+vS!*&RMt?aSpv;?TY*y@AILLKPJW}BsdWs z!>IcaVpHkcx9c^kgowhP{9Nx@*WX7alUc)IX6bO3TwAY7TH>|$p>tp6_$Y!k9~iKV z6a*I(7A~~cJW8m`klia14fbA&A+z9|;X8`EBsExN5%K;~=huYxpg93ZNoG+<(Gs2> zopwTYulR45K9@#s-ubjxP%{=IYh%fskR3ac!uv~kW?_#%cJ`%3yKsaYe9g0unD)y! z9wc}}al&N7SkMBD`7RKio(WAHEa;r(8EdWf^9i|n5X1z4C%)uP-pBmh_1yeUE$vg( zf{dmBo95~XE_tt7b(;6(mG+Dlqng&eZ-f$g8)S5{)Ma4@49UUuCcG*70_w2j>n=1t z5*r(<9_osS_)t~R*>TyY)v35MU_6&CodQ>0q`(4BG_PNbYHi#bx@eaDWLPfj)`F5b`yOIkv$ zeR3D@-XL7J+*|f#=QN0a55}B5cD^Zrmeig zx&4#x%D(!>BQc~e>>;x@3XLzCiN1FAw%V+=pFeHV>C{Mz!Fq4irK1E3j;C-ik@U>A zw|8&S)LpCjb}Tlb#WP}bZS$+Vs?`e>$PW^%#T5*;H@8GYd{MXh2Jz573{SiyXB89=bq{dN)n+TN~Dz`4<0_OwJB1? zsf$+^{-e^ozW4NFmFK2gPvh@@3ILe{)O{w=uy7pjTW_-a*23@;tLIhxara_D*T&*} z=o{*m^Pp65E+jlWBSRE+{A*zw7sX7< z^krCIqq?cpy0NkL!swd2`iZBm7kfT8IpLmD+hOmhClF^sc$LyhH!8&!o5E~{?!V}0 zESWQZTBECteV_}D>&&tG(02Jrmpyh|%I=kchWWo^_@dI5uhe|}yi$b3_^*Q$M5 zS9eKTG`~Ek{c!85zn@{Sqy0p~#Z4_jA*T{H1Dskf#loq{YF>uO?c1J@pFVE#Z0u{) zsqEZ5B~ZCwWW1AEYf5bR?xlp1_W8EJxeQv~6HquY_^U&z|Qp4rt7~oVxtJ=)-&e zcdfAi>lUNd^`72AhLa|F@7K-++lgRnp6yhb-@jb_Gq0Ct^-tTIQ@Y;UUtIsKb&hR) zJi)SF|NAggk7-<>_}H)q&V5&M2gns6J(m(nOG|@fvJ;CIEviweF11yP6(}w58GFq1 zP{qvHg!S$>ymmdTDD?jOA6VDgAEeK1SF6>UD^Z0~0&cljrpq4_D}sA2wLzCvIUnD% zC1fzPBO~F5mvy`5^ULvh3mYjBv}kry`vg`{y@^HQ>TLZJ~jq@ z`#Ka95_06@i|Z{#@kx*e?u;MBQ_ABLy_=1G=r6ilRaNo&^%^P+-O08teO*oNCMG6- z7#VQc_b$)ZTDtBW(O@Mi_@OO-;)B#FMd$kJ-)!W7y^$ z9zRF&cTB>7?)Rz|+c1;u@B57O0t?$@nN+g5b!W8;lfSdn_aj4&s->>%jq-=hyC zdbb#5rQr_hVVhu3zRy$U=`7b@%TG?Y(bP+jwKw z2du9H{V@$Z>vqjtZcQr`=T2Ah%d8;9weKzzr49O!}kfvWq-)8(X!%u zDmo|fzL{sMO<=Kg=h-hR?t9}}5b>?3&HpG7X+02^GvBA_LuvBKP{>{TW}iW?(4IF{ zbrHLs_V1pNt={kK{FFDE=v`g7J1N6%?~yaVEa)pNzT$aG@^zbuJi0SfFMo^7cHy+4 z*pwO{+uey@8*}YG_!Y>1nBG=M@f|Y4i0H za-O}uc4GQ<&WO6_Z+4ywR;eIN?P=N9KE8Cz$;o+|RuL7YHPJPsdFQ#bRr{RcPQcS! zK%*_r6t0T(Ij!qc=#t>R=z{&JmhSHDYj!JjHFX+0!AI7~d0(B~ z4#N%1yH~IJKbfoGmjhd=-vaQ{Pn>w6)KT54_lhT3lDJj-hLv1x4>}I(+^LSZjD9{l z)z85j9xZKxxQCYL@e~3{7A(l}m1k-5ZfNLg$ zR3fqm-e`}&$4!>UPP>Z+U{@+qIw-^qAUDG;r&bLMu60;Xm5H^Cl3fL|S3y?OU8-AK z!Hck^-t2{(JFv;AcNr&`wYtz?@O;TnT=rWy5(Ng%Nk6mkVMYuo;R-z9s;Oj|l;FmY zrtnz5~+|wJqWK8 zNR%!Lu`NUrNSDKTH1RMY5OUdYVTST)e>i7~XW?>#O!%RIjZmSK5(h!5dIpw)yEN36 zj=fp{<|8Ev5(0P)*%)p_RZx-#u|(-nvG~r0x^BggLOp@`NN9yAmWAs+mai3-RfDYg zbS$d@Sp!;j2xJv}94tKk%FVG?C76;2aJ6tBiT=aIjfE>IG3<;XLh8ARJc7&dQ~y*P z3%pFhdleM`{#5`MOVwvUy9}^bAng4;#^3;`OIB03;(=_WK_859#qEN(F?cb+K`PEDsis_!LT4CKnu=wRisQyqQ>)?3ExwFJ u19sVdo`~cY)F|w1xO}N;IQpOd%@~Tv^GsF#*{R8*>Tz{iB)uT<-S>Y2yyexi{nxCN!?O)hSPPhLhXLl*FMT zgj|Ypi-ahQnQjy_g-W_9N2QzUx1PP5_xJt-Z=X+m+Iy|<{;svxUVE>-pJ*R%*Ac@E zh7klY!rjfummmfS34*(r90D!Jw?}S*|2SKHU8Tg8KgZX@AH1zn_xU9J$jMbof)En! zP7d>Tp7>O;Z2z*dUAdZVF0JCVHFwT<34Q+g-Apw0R7~T$X))7^b>>?r{4>X%^%-`y zP#Rh^YTq~U&+)F)Zd5tRlv|E9<{2%Se^38YQR4R>doSJVxc;iUS2i;-<#1-$`>a3T z{uS;%6vqCa{m8~%zo0|x`P>@k?-iy^q+h-Nb;-eDhTdTWVR?2(=h?_^#!RUr))i#BF@%qu#=)s7YT;0dxM(I(y2%S?aJY090`&vX z^9Ym!I>Vw_olOp)Gn&;IR7nYm`3RFqgE1FS?3nLtKwX2>7kh%J6%vit6B46lv%@nl zLDX576_we6=w>8ZegK$SAf`dyprwtpZWz;qMI>t!=WhT|n6vzHHvqsX#3g+e04zpY zO|A?s4*)_8v$(}G(Z8{zXw6>0#l`ktI(dq&8=L|~68 zO(ZCg)+0bY;EgQUOj3l4DdMsdxTGLo%a+1ebCFvuB>?*l!6vY90ZH!C_R1us&0EKAy6+n+*&}9I+5`ks{=zIi9 zfX;77M`+67`WPa1btJ{?LzL+xf^#0b{|_)}G;%NF3`*~jl589(St6yy&I~aMW4;1M z4MuUxcmdQy1eJRZv>dS3cff=~Owy+S0D%C?VF{8bY>4eJ>s&;d2?Ky+thJoW6AF=N z0jw+@axZZk`e|%{IfqMOt~F+$kGYDVKN>kL*M~>uDln8AmnRb=0+v=Bt|bSd>O%nN zA46U{0LC0}W4%s1F`)?;^tS*Ne6OG1lf~7kHqbdO^5%*8zaMQIAEhXfJCd}nD5SWEUbpdJ$B0x_7tuaU| z*#rnUA_6`J0D$eXI81OBqvS()fMXY8fZrjSOtDrlXkpRw5d^|(H+kV07(-IYKOv;TVH~cNGjgk+ zm}b`C7+cRH3wg-YKmfgnK`#U7OANZ2%R7%jGXZn~0)@Es5h0y-k)VU;=dOrm)*(z{ z(NHRR7#cHo8<%I1h&ZJu5S)E@CMKKH%u3`wA`L{{uxJQ~9>SvIINVW~Y557z60s|c z2!h1qjNC`u0D#YkA5%e6LY%v0JGeX&e259Ihu`PWp!kjv1a5?b!?wi?#LuY7w@eniA%o#{+0cN@j(Pxy2(b zhanfqj|(?81@{%HeoD%9vO24k)ieyoNFjw5-a&adJHCO z%jK1;aepkq`HJTt&y;3PVpK>1@LK^~cUQI-}VAkz=!a|&7l1FfP2G~KFjtuRHN4h~$fjG+)!ZtGk zd+iN?Zo#10JaRq;4FpgR3`$bx@y0+yinxd|3;9AHKAIl}HlZUJD8Zag<{}_sKS^2O zNz0wV+3}qH0R$gSP|5Yba%bx2s%h9yv;i7Mtv601zUdqz~tC zA7Fqc4~CXufF4Rn#i6Op&Eb(e?7o;NB0`3YCbsZ}6h@`Jxx7fswZMy^39Ro(2`%w{ z$($mo1Z-<=43G45!UO`jJTpwd5(2;&<#s}UKM?^3GB_#`2i%!lH$2u8Gg`*Ou=4;G z?=H**lF}c5jpLEp1F-A3ydfBtiXbBXzyPNyVa#D<3=R2k1`aEw3qudVsQjT+c`WXq z&*gm`&_6~*7-B9?=Cn);i<(lxbR2<0sm zM`H>2*KT*8?a7lTy~6Y@EjZlSD4Fd-|7J>=Tof6uMu;06Q!QQ5xc@n;hWrO6TF1|X ze)j_#UB)`>zwD_Ml3YUGzuJ02t2zIry^X6lhpfkg3F*KD)aw3W()RySU+l&B{1??huk?iTQ4$?c ze?d|gQAF0DESy^l`yKhOA&`=NOx2vjN|h}@zTPMcYSNJsu+F-+k@n{*%wBsIxMRd{PS;TC`09BgE$qG?p0*=XXr&(BGoWCfyNO4> zxc)SK_<#Tx(mH+Zb-Lle-yH2ZOzwJXLu-+Q_1G!_1Lx?vjIQ*3oyaBaf+xnb?2wnz z85?z}#}ZDV!^;oU>0wHhk2-nezB95!SD4OGFZg)?@uMYF9N%4An>FACn~~Gm_c%L_~N7g{&TM+epW8JaW~l*8N`C&)vg6z(POfW%)0_RMX-{px11MzguQ zvLnY_nsB0>-(X71R$9NV0Q0&vMZ4!HEKM85P#@5Q_1~YMam-`a{xTOA7n1mj zl8OVJ1py1>ZM$6*mS&B@Ob3P*TEBe>6x4aH{l7Sq0qK1Xvp_UJ&)-vCli>xTDsqL} zE4x6*%uLXeMG!9Aqg8z^qea>eLbN`?E)eI{6$z+Gopt@=#EKJ_wicRkxDi=7KkZl9 zZUNN4bVW6V-Q7c`=n1K%Y3j_*0^?ugZT+77hZ4VKWz2Bchzj4VnIie3FP3!gzCo@S zd-?J&>=|uX(X(@G^9*R-ORo6t@}+=WNbkdZdurKcV`x4~uF%W6x|~e_qt3nZS}L!Z zz6P+p`41;%UHO@tWV!=Y5 z37=bLC0P_ zn6)4BTwN8V0S)bgEsg@HSGx#S=iGU$epjAWI)vf~{hmiKJt0OnUPw=_!%-V0pr=CH_oaJDXq(NpX`*$6P*06`*1JL~uPH(t zmsSm8xBQeXVdr5$J$mMLpG&kB$DHjpxP4B%)^Rz6- zaJWk|njDpEVhNg~(4HeF0(6DBKeP&5*ku^7L%eDxjQRKbQY|8{RA;0n!(Nkdf2uU+ z+n48UpEm9eZFqDcvXeL`<8mjrf9u++ISd}oH!%@tIG%7q)OM5Cm`lH!OPC2z5=AIg z@0BqX;5rCC8BrCmQ@kp)YS2It_rzFg4T2U>%DPkq$i=JdG#n?W<>8P~!WTUUr$N~j z6VaKFNZ$6A6L8XC?4ngOoeI7K2oI>^9OQY%(mX8+4zcBjJC$i4NSF||{?e*4&KYCu zBq!j=LHw*M_z*Y&a?yc0pbJ9dup%iS5D#-rO7mqy=UEdZj9)bd;!S zki`)w_#EV=se4%Tr?6e>R;Boxx+*&f54fiqLkZd^O=lqnL6Pbz&rCVP%1r^IRGooy zhVsP{<~Wp>WqGdIVpeG#RH$%av__%SNp^t>FR?RO53!pB<(!w?a+;Lw!L^_4*aVhO z7R+sIo>rqLANT}9Re9W4QeK+CLNA1J5N_IjJ&3xZp-Utwe;LDey@IZxRZ(FhP!}!+ z3rv4u(HB4w2o=Q5@vK}tlx%)gQKy>pSoD)n0Gdej-%N!rTo*oAd?T9DaM%mD1$@DQ zUt_^OVk3YXR7G95w2$oq7hM!e65gC28>$;iNM|NuRqd zkfN)iEDxzvC0$*+Lb}`POZRfA-=Qe%P`~|VR&g(MN5dl~&e!9RM8+^C}}Wvg61SxSUJ z>uCPNQSp!SgREy?e?7V4?yh+X;;tFZG$^SjnG+==M^*-1zq#?P_m3MZ$F~*|(kf~=9z}W1LMIH zcCpkJztMt<(tz;pB9-dTle2dCdYFmmP*0jMOHjl-y7SbvqxWJ*kN2E8UQ(tufgxU4 z4qYKg3j6vxYrVuK&HHvkc-Xiy1#x*ghjV@K2t>%Cu&C&JEhX%*}$%9Lm*cfZukhZ}0YZpy8yFOO+=O|6l<`p*Vx=dG)7yeFh zRW0=2l+(1n@0WZtDN_vTWVDmp$#^eGyqB%m%fVMyM8AgRZ6H1~HLWV3Xz<61tL@8| z-wQF765HY4%33IG`26|(qc-@R)G}rGq1F82n=KWWznV%JT>u*q9dpf2-nl8I82?targ?LZZ|%nD2XTTdb<9W$dz+BAr7P?5;q&+iLM-vlI1vjydk8jZnTb}j?y_LukU`?sFmYBPp9HWco|Jf$nU+Dhh>q(b8My<`1; zar+6?0#7ONHGm7L*4<58$H>+#NfHv*JuaicMrGBpHEa4%j(7%#Q;=t}%8%{s82its zi=h=?kE{F=6hskw3+Gf|Wn{ZEM&kD+=0Q|c)V-@+79TRxRy&atWTXO5#ev4yITH7l zzaHm1ylFbF@`^Kp?T+gNx2;2j(kGgy=1FICjO_h8*EcrrT+q69(Q_pwEJ%dC@gp}x({b#n9XXn8xQ|NF6mAB!Ki1-#A@oHP*F+?oU!uxTBj6*U@7z94n^ zACFx<#&WjAjhSP=@IqK|2CS8HLiWm1`n8o6=auO>*B4XOf33M*8x_Fk za}NNM18$0@+7y+vrb=K79MBf5&VaqD3^lW zkGkwype2yU^mXl@b|uf%W0AR_;=-cdMoIToQ?FU4UDye%sWpHLXTN)9HBmYexBj-r zW6LUAssj3s33~VcH8#5YeNOf{;|9%?>f@BqT#sU8ermvmS1mM z^W|`H!)N8pUW+N#@er(Vy+UxZbVV)q`@_5UF7Iu4wx%>G_)J;q>PE zAz8tV42QhFe|K4#nL+QoOB>oMv+p(=KbGvi^@>e9vgL=%HZip?L%a$? zTkak0Yc9K=^Tq$iuDazxlGz)*A2lRJj^6RLXb5ED9!m~~ymG_6pdx!m$zMr!KkvMm z7A`*%Y-c0>w*0!mh8}g4JDCpqybt3iu4%5wuHX2vDrNZosggToeUFCp*k?EJQcrDo zG)w(r>iwOL3L+bhFTYvXNt-M0sr%MEs7VREwrlsp%_$u={fBp7;w8LTQ~&NA9ehb7 zWqySW6d7kAS|)FMVLu zv6$aRLi(@B3u1^ppMDfT9}X zvvQcQM~{Mc?o8P5&*HcrwH*{h8f1@$&ii8)Xfm2kMgD!}f!Xve!NI}fj6A{m=ZlYV zCQ_!-SFk9b3#@O|ZO{JOQ*x(nrj5;;svXl!_}s~GTAVn2n>=1fZu)xM+)&{GQd7;Q#gQB+@{^?j&IMD;=( znUJKod&D>7<2zwRPS`9%f#4TA@0GfuLTiYQ+yC%?uU?p)KjEw(HLm%e+r~BqrqX2g z#ffv9)t%`+q1WtwWW1h!bzTsq%G}#VRMAwI+?CN5ah z_rN(`sRMgrGF-nWuXrwAC6VMDnc6ICKUrN30uzg``z)Y+mZ^7#=S-fne~^;Om0 z9`z^VikFWceFKR-IH1b*jvR7K5%LsZGrr%y}wa#lge z+&aCV(m0raDC|JDYCk+bTCd)i!xt#T(&Ui<`ddy{t-7u1@%}hCsE_1xKR|#?Zim0y z+RK)w#^q^kR#NQEx$LaS^Eg8g+*kEYn$eA#-jLg_@t!MQtK zk1ur+^QwSHlc$0@Oh%LgdMIDyWFi%^Z>E(AR3?=vc&-p zgvE~KVlGv>DRO55Y%GS|39wHw>|}sFgJ9X$7ugmB3-@>g6^XFmijR1Rw1hC>v<2#~ zfjWtFMFYS?4g1iPV@2I~Co{y;GNIx6=qQC^$M|x*WAQT9!LA7>UAlEPQ-`MA63w$j5Mp%cZv= z(OW|H+XX}m#@~lnvoCEvKd|ZwD7J`;h-x7`O452r2dyF;5K!&@~9Ow0Tp*AcC2|h8S$j@L>k=zx-j2^a+TzD3?K*4};lp+?~Ch Ju1IB({|EC_!h-++ diff --git a/third_party/test/golden_widget/flutter_logo.string.color_filter.png b/third_party/test/golden_widget/flutter_logo.string.color_filter.png index 0f02fbfe18a983b802848cc90e92329fd572b611..d80af0975390b8ab1d09108ebb7d44780e376578 100644 GIT binary patch literal 7618 zcmcIp`(Kn*{y)#dC=Y`23}{|Z=E5yk)FCh74ToWHKoCnE!$KX?7A?~8l9I4BBa=HL zgeYcsCpD`{Z7O%ARlki!L3zVm6hY#pGwT1(e}8;yz9}53+q=ev0qe3 zO6QsI6BguR(?G8M{9I0-@p6Rv~sd^i(Mwh`SZCj5a4 z8RmXq>SCx+5EZr{S7?|kG@r`)Fxh>jnq;OFmZcSXi{Ue!p|?IGh~C!fKv#9(Rcbnt znXU>~laLH%`WU7u48BzdQ!6taXo4wARH&h*9CZ;jWvJG%f~X(QpngGABg@&E1YtZA zzE6b=)H(*jflT0#DV z9YxJxrl)|~Dl*dtKt0MwngdgFOj0d6nItNRFFD#LEC*6C8J%xdxnOgAee zy~K(;6ssp93uFlv6_q2HFfY|cRz$Nzh9Z$H=I$9Kh;?=r=vUOdGM4F&p{7ABre!J; zjbn+{ZzDoIH(ibJ5v-&7;n1fr{Y|WgJhsTlG2r)P@zr)BEX<@UgA7J`+%gSobO0Nj zegMMr;=|w*%wnq1kt#0S2;m4W+(CrIB9`bRB$~wwc^-*|^FpIVMPnLEq~E(RUBgYI z^(0cwYI+_}1>AH2OnY%tpjN%ZO#cYf#cb(#<1zA4Okd%Go_F^$LWQXogsHqG3dzGs zr!!0)>0QuQ2^Qff6v0;Q_gu`W|e zO<q4FXElFK6*7rEcY*pwzk&mNO{T7Rz%6spRn0 z3`+H;av?}%JL5^R03Dmfh3Lq3Zb>OMj`snS>OIF31*KZ~&P6G8d>X5%1fNhl58n*@ z9o!U@YUO(erPQPR6Qh(moUI)KO7$M$rl8d4%uPj^O#zfrWfe9z0!sBHvXUvK2J_j0 zQaw*|A^H@|V}epW{dk{2slhzw*OY1xXB7_;4dx+1sk$-T64i%u%-6!zI=&s*h@Efy zlu|SK!UCmQw5-XLQZv~WMXcqpWJ4yPREw4CL8<*X`B6&k9>azNO0^4Yhy;{s(Q#8y zYCk8N5~bAce4e0GyTDOFsp{=q4@zCb{XwZ}w!@M}P^!py`CqLez8R}4zko46$?^(LPTrPM(@Iw;kW%k`kt`VA}*N~tRurw~x8y~`Ao>ft*R zrPR@k-UukwJBdw}QffVq4@$Lv$AzHOk=zoLTB&3Mp_IzGmw-~M_a6>8t{FokrLEsR4^Nm6uD_F7_(pp}}&H5KWbiawO&DmJ1nbt$nA@x#JYiie=-dyeK`5PK!(VwyUtK7&P02#bbeVk%{yI%d0h%=dbs9cY*Lqdcj3fCqjb#K z6>WRE&7)ABXz1!%z%aEwd#yBYIP1RJC-g;ZJt0LdsEU24?up z=ZlJiO3iqq|97CMSS)L<`lDOo@LOZ3O84tcqT-&~kmzql{T5;`aLWGL#>(neqWof* zKe;T0G%(q*-_+$@86}9OFwJeh_svY3H^^A~Z@;^UwZ1{x@_tvcdPxv-Wz7R+SLY=x z&rI!tNPp+%p%%TPWNH_>x(pwct8A&iQ;sloolWY$-j9Y&^<8J#QvX~W;p)0F>HD~@ zM(GIDuCg3Ico7IdP;T_6Zc&2;w1#DV?~qA0?^M}IJHr9!%+cii#k zX0cF`G5i|kkCrHi{-UNh^9R|hMOPz#+l!qZGJMxyrjJ$ASTH& zd8Z{gcjx>a$Y*&U)si`n4tzHALZG`PZtN7%CzOY&WxZp27L*x<1D*0}rAn6|h#F(9 z52ICK9cg}*pE5@pSu)IzTaMpkN8p^ojcDp2b<;0n!l5W8M` z{S{;~qN!Q$@bvKs!Ai9}*>M!zT%JrLycn+X^b^G6MrX&uPq;*>@~8#zr{u zWsCs@jQb7+{G@3L`1lWkn6fp2$_CNQtbKjL(F~in@{j9i&>9-_D()D4vEkK+D78sf zf}HCElqc*RWR4cwVU!8!#yy?X%P2JkRDr{TO8U_>ywveFj-orTlfJx{W~-<{%vtL@ z$h{csvr)9pTpKf!Ro)_)#j?}_zJ=MAT^*zp_y!jZ*nhk^56q{H3 zYY9cGrfA;*tyq$?Ya?mUS!x*v_76sGX@O{`~fwr)iRu$h5Gmd`0gKWhq zzA?9jn%iDAAG`SGNoRFn9qupnWgYdKq%oN1 z-*9`4P^yl|nvaw!{VH6y0-EN(puL{h6yU^_Wk9%UwzKS!D^$G}H?6e76)}dzXyMbi z_9=bJWXDn5yq4nT70?v5PI@z|kZi!^=ACNO-V0I2Lh?C&bgMQUGSeUD@MBALjXV?0 z5vq}EuB=L#6=SFl)F}kfs`Vx8y-e-C!R;>&s%@jFsy9^8zJzx!V-n;W+`mn-YWf!D z6)lLZ#Fy~lIp&2r+M$YIURY|@K;P$%bIc2|4$G>H{>-ZzR7D-x)6mvX%K%)}2KYWd z^mnWV?+he}H>4YwC)tM^_~gRYHJhkn6HfKxeaDBc#`i+@VVWPhLhqd$Les-xEIy;q z>NrMoIFIxB#_GVhdaClEsCZMMb?pJFI*CK{wCcdV^?#r$6cwLRSf{^D(U$=om!Fga zG}jEA%O6$;MpTWYcJYFkIi=9^!Ey?b0rW%Ff#VWsg`V+Hr5Aek%%`eNM2L+}y4m;v z@W>0eOrZ?ZDq2Ss?ttfIm7=OY_@Z&G32WkzI!StPVU>GM!G|ru5T<_iFp|`r0K@)R z5RmhrVExX(+OOLp#WJ`~&p*&oZf?8VFs{Ij=4;D>gqc5!V&>@>N6!ggb+#4f{`>O%2?sl?V68=@sSb}lqp7*^$XR#N@4vZK zqpv7*im4vktv5?k=MSavE~#Gl(}UCQOA&cuKP>9aYQw_4=E8x6*FTYjr=s+>SDf;& zzmHAo^;Ywu3(p!QPmgOha?&?N%FUl<#{M+7zBRY-m%q5D9(}&;;@XJ;mE$nXbcc1# z1WLhd4SZpgO!Xrut+Mqo#bI3^NsG5F`b`>?y*2dwS1D&{JvYz0KYOGbRIwpg(tqV> zUDM!O`p?62KkeL`A?d=gOj8}too#Nu>+bxmAqA%zwm?T|7c6pdFuWK<7;86fq?-nr z-l`ny?U|H0_l)Fw-rV*%M)F|ZSl!sZvTaUNFO<*EkA^?SU(|Fl&fs;soqS9N1;T!)c;BeQ_iEW zB(5^egiqX0-0oesCoD(-z#96XBK7~F2eZk?hlaC`G=!3{u$w-{ILj6ep*xxIGX3Q$ zOB+J>7(t6)-HmCzeZEK~F8FGKLyk1n-SYLPEx84uL0SVNAC2Q#? zov}8yy558u^_Si|C& zq)w=?8R?1gU!reAii4a+Oj*0vy|bp~yu0(0hLrsGB|I3YN%B+cW#5JjSRk0L7`tOF zB2(YWZ$TR+@a+qh``{^;>`Or3a*Q^j*f!pPoSxudv^w;s1zJTSUf85(7hyZ`x#Y%p zP(3LJM^yY-60-23*F7N}s^6S)BQ9nZbrHy}0^v)kYQ#dSf)|M2qA!A1HoPM7{MCI_ z8dPoYngf;PC+wjYV+^)&sO0!N$P-KRFbW8l!1~8AUK~6~tTIf~RJ6?~wTgH!-Eamz zRmGCf5Chfu!C<#grABWC!r;3DVL0C<>uu!Js~>^gwoi6=n=rKM(KuHf|H>%EXWB^S z;yqC1K!xL#R~&%MEBh$%?10zWg*aFhU4$LF9)JA=?DA3_UIXl2K7-T4ajL>59)GhM zsyk4LQ0*?Iss^K!iG4c$jvcCpT7%_fRJe2%&OVjTDn%SJ$yJyo_fU%A`2QIf9!S3} zy>M;3yYq&-({g_TK40&GIkzSdTgZ|b$J$=KpxX50=7t;3?wa|hyP%(fP~nPI5E{G9 zJ-GVGm+r3*xI^0;#7k8UZ*-2H#5JM0}bOrs0xE0e`-Un<0gq>87x~G<&uoX^#2Y-DBMjE)B9D#~%ppJ>23}jW3AQJh@sBoD*fRSisb+ zm0$1g{JzF~ZNGc{Lqy6i?G~^M2_*0Otn;TY-PaDd-)`X$0w7A4_0jD5*nOW`I^}*P zaoJ@1b)=2#_qda;0JeF|Qz0i1znl``YiEaRuHEDA$yIo{-~4Gt?WIp!=JVub^wBz6 zX?R*G9>=qMU!}$orjhX!X-!~4JA_l5vcV-w__h{Ka^Q5WmjzKjUF&#Gt1#eiCR@Xq z4_1OFi23Y5mZPH#QjCG#!@T>9(g#Lq1(sL+c1g2IviAZejx`A683FxbroWR$|5C#I z$I-u(WYI|Yi*b_JzO|kCU*CUXwH%r6>_z)8_ zRZ`P1T2m|T16~g^#r+?D(PE~naCQpes6$~ooulH_(K3K#dJr{ZGp057f&U8TkJE!? z8dW=Ppr!j*$=O>We3c1bp~5)Yhiq&LmLP74iEP#|AvOccU~Wl;Y$DlUe@i+O-h%sP mhFL)|7g3>t{Ez>2cD&sfvitD-2X*x{QhI8Z@u0!7=KldezF?aG literal 7518 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 diff --git a/third_party/test/golden_widget/flutter_logo.string.ltr.png b/third_party/test/golden_widget/flutter_logo.string.ltr.png index 7e70b9565dee51aef6a52f03b7b7119a82c15361..e4402865634cfd5469cab823e5056404bd347fb8 100644 GIT binary patch literal 3404 zcmeH|`&&|X9LK+hY%;A7Ej3qyNa}igGA~(E5#m7wGqu(-)6|-)P`fBzf@zY~25Lz% zua&deEZ1Y!R&!b|S47%W63Q%1%P2214ND``xzB0O{)+ki&q@lq9 z^G$3_5JK~LT+T*>=1>tLY$1LGq%<{aKU^@u#sD_D*tTR4Zj1zM-X7eyu+mVpJw$1M=DOs z_ZnF}I7;<8>8YsN!a0$BR!#SNO_H_y-wBEeG<)pF7r67}!6S+7-F$gTOLvi=t)c&v z%6Me#wa>Lbi+b|}G$>?t%{uUZcfhGO_Tlq8nhh>koHx6iTRYd(@vS3AZgC&`i zDp`PdA( z+54hSDZ;20eRIT7kntM_Uo=pFuox!*2LXJ9gCYP_0BZpl09b#AuyPjw+X0AhPzb;g zfHQzpx-V+VhAj~|fGi`tbR=7a5gH2>#z<&JMF})e^--2|iZN{CQFWuZ83I$F6Lz)l>{0dN4s0dN5DoCRCN zdK420F|r{>t_4O2-3~z$?OAAfAV`lJ5m|GkB&399&s*!T#x)jHv6ozjUz5yzCjU+<{zYOSrA-b}@EnUK@% zD@opARW+lX_oZEPe9g6Gy6^PJ$vEs13OwtqBlDfLS34YdJ}HKK!=^`D=fpTcXu9H# zrNWps2(^znz4Vvs5j6nE!IUzFB{{P#MFM0O5KhuDGw=(8R+_cucF@mOV!G_}I znp4rT0^SjD)&!glOgK*@gArncIn^Da#op6zsrRCgna3oxlclSjbXe$T5RqWWmYwOd z7dog9tjX`R5C%Z1^K|Hg%VpJZ+BTuW>k*q2Slsc zZT>dOlKRNs0L-g@XdxE=1Rh(Cw-c6AvX zgB5S|1NC8e30t9rRfQ4h$xoJoHRTiF(t1Yf4;j>lpjc}6Flwe(b=w$0*OgI*iHk)V z`f)4Qzs9PVJ!@uej%H5jYNirG$ZwE!G)R=ob+D1udwD+bjB4|VRZ5iH!pHtPmGwdX6Vt4K=k>JY_v$GN_jin8Adu87K(vC&TzzPvX)RVP=?4EY4rdXok1uxWI PNw^z4zhKTqc1+ek!J+%< literal 3411 zcmeH{`CC(G7RTQNlnfY2SY)e)B!hs`qAgN^hTMrM2?!b^iZW~p2!bpM%9cuoLMJ3s zmQg?uQYcGNS`btE6n%nehfw#z6h$#e4NK69F@z9`s6FYwQQlwji~Cw0;`> zLzVK$W6i_pzU9-IG!U|KRvh@NJJ9~!^QNS-mOb7$g>#1YwftY>n`6FQyRbpN^o8g_ z;4=nV#8QW?z@3?bqF2_%FXeemW8d4wgw1K#e~{HLQvTC01AQ*~lenfB4r8U7L6 z7CRgsdjV-loW(x)S=3A||&Ek^r z=0cUo8u`*ObiHH|H97!jDz!%WZWwYD1E2u-7l0)b5G|rO5`aDcs{zbN05}4W0{F}X zN*9r7Kxmmc0V6`yfhvS+chcb$+ihLZHd-KZ%z-2uA;~@{ zlY$8l&mMr<1fZu)p#Zi4_|gQ1oeX$1-({)OO*vE>Rp~va?0fF#YsbD{xQyW)3nA?A zMG~bT_R7-p6!Gt0x6AL}Qv2y}JR-~_oV!m==ihedxzD(q`=Y##Q!{$qoFB{bahayel?6Jg(F16SS9HHM`%UCcpy+vZhf=QnY4{PgRem3ob4 z)b^LF>1mG^jQ_s2sOO05Efl%n12H0@ILdE9eL-oJ!5FK1VB>jSbnm(}h3R7$eJ<5V zzx~>FspAKKJ}RS*Q-&$c)%PKJmoJ43K9(ReklS;VJiFzlA&Hw-#;| z&Ac%WUa8bIwp2}_exmT*X#ZCU9UmCp-1uogH&jKt^NpA!3?hTU@fCzTy^7qxEiBN z*3tvP4MeGgBy5AFR7H4`Poz8<>;(%xlJ>aApS*K}vw45y2ghaGTt;LZ^?qpOTkWd= zQ0N2-t>+sFem$8pD)m3Rw8whfX^FF<>xWMs_Dv7did^=V4;0L%9S=DFEU%h?YiHu{ ziZ)+yMY2_^Kg)@bT?iZ3Z}lSMc})1~^~v=k8J{o`AM!FnwN)U{0R&>z zgk1+x4Fo6)*Un>CK0D8$(bSwzKW-?y!X?Bnt zA%jftT=9c7BWtq3OBppJzl3e3Gvmzuc_`YZrLTBMNLai`S mgdK&aD`&-l6$iip#uDYjYr3_J@>F}1AHg5*Vt2CQiv9o@we9f$ diff --git a/third_party/test/golden_widget/flutter_logo.string.png b/third_party/test/golden_widget/flutter_logo.string.png index fc9ffa27529c1c7d62c7faecff5822448e6a262e..7b88eeff0280f9170d14a57356ba73fe922ededb 100644 GIT binary patch literal 10330 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 OceTRWk)O+RKm31$8ZSuz literal 10130 zcmcI~i$7HB_y3+TW$R`SLZ#+HqLU(&#F(aGCf@iXCgCbEXVYQxc# z?#6!;ymklI%i8<9tZfV5T8mmxy2i#>_e_;jI*$&YplVQWY&-Xtec{4M^-8+uHtc9q zw*AgoJO9cb4NU#O670AA519u1K%NLWyXkjs5>=;rs-g3?Of=)~o`4+{{SHT*1|8f} z{j0uMylB_XHL0z==fBJT^S$Qa{rVJO^?&&%e%&8TL0;Zi9@4hEIR05@^FZ)i!;Ce> zgCz%={9KzaQ1)R=WP`mBJ1bB3qtZkRqm+3nj1627;yhQj%C;rK4#kk0Y!13c=uD?j zxu&IxtSIG$+FT?nT+Y;ytvW$Nkup_=Scj99h)~kKTOuT-iZfN2h#Coc2te5cD3gom z#o>J@`tt$lR|3fle|wU6YYa%%7>@J-rBF*g5S{WR2*u+iq3UKQLJZvqd@XwrfgG4h zu?5kL5O488)FVX)5H(5B8bp*79YqM1N*J3%XCh)<+^v#lVE0$j*i7I>!tTXYV+qyG z5CI+?=f#`@?Ifz#d@h2n!ow!&g8q+*2&B&hXLk@#FK2`50fM*pIf#n}L7-r*2zj{z zkE?THzJBv`VQV0*rRG7$2GA;m`?m{9tiI5Gp1kyqj z6a7UZO{Y+u>4aN1Ap#4@xE`jV+(`tJECAIbLF)i?5((-Hpw0y71^`tfKoMM%oDE$N zph<+&B7M-r2u(u)XmWA$h&rq%g$4KsBKE+9LV$`qK@1~;B2vZQlHyGKEr~T#3Eq;T zDgKsN2O?AaEh$ciw;u@F9;>M|rXk^0eKD$r=J# z1p*a?mA)6|1q3-9oY_kDFQK6&CkZZ0GYU1IB%q0as7v(HguNtxGAUvpvPn@BL@FsV zDOA4+Q4hpv7YppF5vqET2&JAJ@e{zCn7POl9j@pz z8LcZc)Y+8OyogY4&L`%^2~{Td92r6?m6k=$tqpL3Y$PW^G>WCqCc@%8i$dK%>@>(i z0Bs>buK}nD0h$G%(In_O0F5U=!T&@75h`1KB`lqs4J8x`RgG9~$VC=c#3md;1Ssb5 zmFOgbz1+~7Fk0e5rD-lA@ISbL2pc`@Ss(ZyY7wHxd=N?hJ$8afM$N+jL>j5Ek4i(G z2nzKOARe&}kY&1DQ9fxb7sc@N17JP&fGWwh93pUq_bOFp36C7c4@%evl;n+4X%|UeYO6(vBB^>6cwf`uz#f9A!5-EUaj{g98&5+w zkRIxtN5Y~>d}~#vvp$J*luBC&ePD;%uu8<;Nh0~8SXLzAmNT59=g7F;)aIsBNw?3@ zP&E=X3qZq3(2W49M}i)w(x#B0aDb?hv%w<`G)bo&=uBtQ5zz|JBxggu2nh=#Czcye zR3ailwN{HtxTKiE6_p^Qcnic566=;N=uU{MKzBl11G=QRmn-7>5wwvxDol(VtrB$_ zN+Z`ILf-F^KVj?0e+^ICQ-+`Do>9BZ?lg_?m zQ>d22l1IFgkg$0qfdC*NB>~LY-1OBXm$@p;m*jCKidDioCSa9mXu$;R0xE6G1gtiN zYCytv0IWI*O9QgTBv~d6^&(ZVNF>aGv=vTgO2SC8Tq^B<6YYsen88GUU9QIjmnTYC zJxQPhK{2-kqE`tQ#0XLpff!GUB_I;8@nx4d!{3+O*z;!0vH1<9_L<|ucjL{8pEopX zAk{=XH$Upkcro7F)6=7voLDs&Y+z_DbT-julDo3@=?J-IT$y70`_YmEjbFbE7opw> zNZ5RwecYl_#Z^(tH zxmiT!OWLMPMX{U2ye5s6s8Ge^X1_U7Ib4O|H;uxp{!e$aFyso64GYv;BGOA0VS+mo z`{{)BO(vg5s0bk5#TYPeJ*L}m_0F%uo?;9VFJBk%_$Xwq6VDV1PX^EQAI~fbZzdnT z{Ih)$g=Y%SKilVnJA4#URIso=@imPQ+3H5|9n{Vo8h~&qN`& ztDvD9Ratu-g`~Uq@~DGnhab=OFckEslS?PuD}Y7Ip+EiW=d**TM2-G5>c=xInG!Af zQ2jH>^rg%n-h`_%CGqGiCHDsfy9%bqa z3p8qbdRCSxK8aM;gP^2FN*sPP9H~kfx+gpOJyvFBSwHx#gd?L&S~_X!@m=Px)j>y5 z7GLx40AslGXbR`GN$0o6J2daBGMpiYqeM!kgJtznsTjTD)S@s2qKDG&PL{=&8Oe-T zyp9OD=&2Hh^2N8fLa#eKp+hA0P=}KanOHcTC507oi_TDGix)>KXMrOkemS*8`}Fh{ zPoDUtu8cC1&cqVYBsS-6J)5J;NB3b2JV^_SlIU=jKF9E$DW!@VY~c{uD1eZ&J#hnv zKue!ORdC)Z25ws-<6t%}12ve(+zm5XU_iYU4CE`xD3He)GB@&}>(vPPMT~W8wGg4w zPG0XoVg3YY;s!QGD#O9e^^ioL!DR8)%D7u*v2p~mbj_@*Y`)N|ny{))XOzH2P+=1v zw@Sq$@@ujjiN%4Ztl-R>Ql_fUZ$U81)2Bt_;EbN^}&$y^-mh<&0a<^n;K{ zmPRS#8RHanHV?*g5>8J4v>bV@%T4!tY=gT`klTqdN^Bq}Nxy*muZENJsxMW{hYQEK z4iloQ6uQoWq1kIK;#!+W;eJiR37@nU!gZJFoU}MB2XJB;ThwsFveC@RyT0JK|}Lj&9Ume*KDglUv|e* z79WE?$5ru5l`5klN@7u}`117Sq9sVWS4+msH>Qrm*JNhFw|#01g54`1HA-I&x3>8$ z85`MN{w)f4A;CLL-XTUer^%7y3%HQ9FfOaGa#R^yNE(^ivg)byLrY~8F_bKp(ix9c zSbs+;<9RM53+O7b)_jf#?*Ap{O9guDHi;bJk+(Az33=1>?5UuIyS6TBpPg;l{2rY!SE?MYr)maNoY8q=wu7`v}CzQ7>b+v z4Q^FiS|U9AXR%ro^uVv1IvlrE47{lYn#@}wOat(yEV!XV`K+F+fj2=mg5T;43W%m? zXkv28(_>&-bD=EZY$01^vjX>cqY9G?XT3o=9fvqiT=2ZBm*EgM0Ub(IGxnO zBsQFH$Vt{Ut<*EszqV^|=tyx(<(Dyy(QR|Ni>NfcSoDhhX#pqsadGlGJJ4~oyAkMq z^hM=?kT{fb6A;)@*u$^y6XH1Xw$US%F~ZEp9hxyNwGIN?gyjB~p#33zBTaQL>Zqk~ z`}!>kd)xp1$h_^GZr=dSc|kHGyKJ8UtFfA(14Z4V#qVl&D&Q42YgJak#|H=8Lprjx zwHc1S$-397clen&`WyDf>r&3@(hqe9FE9Q_;Y(NhXUZ^K&sw6eL&tmGU0@vlTw^)z z@#%?fcbu@osc?2>nN;uEtIUJGE_Q`qLa(6|{Gz`Qj*O!Nq;{jftXeDfXy!WKnjKya zPK9rSnwkubEaB){)r`0gy;dH**Hfe*8iOI9%@*&o7|A`wczCGuc7xpP?z@ftX1#Y9 z>{@Nc`j7F?64HJXepBAB!s1%P_{^j~)m48c9ZQb0F5KSjSZL>CZvM>pzzg4Jg`s}6 zdCg-hw+ojb!BAE>%t!yNKOOf%YjdB`{G`h9cwLCwT}Y?@vYSkUFU zwKW_F>Hhdj+DJun+A+UFk`M1!FcRqTqYE6%q~_qPyKc9jJg>R4*ghR!xvA){Z|}<8 z3O-m=GL~L^?bdhjY-8iQB~7|KQ7=@sba?fBUCWCHzMivBOO1(prR8wPcScjHSgOOR zx$Do_bxVtp@M1q7b)E-xAt&*x?uKIdUw=Be55Ia}E^Sh3_X&A2)OIE=S3M*=Rn_qp^V>m4n0Tk0-8D;xJN(DaW4}7GdASon$UPV zIjQls?$(|vi0ovWA|KbkOY@tVkou?9n!uSS@s$g*Y#A_d+%xUOa)CSu-pR8 zk4br##-TWr>zkvpk9M}<{_!8tH9O7d&ar+?l5_}+ibNo!^A zL2Pa<{j5v!`^DO2(kHGnStW3Z6q&-|J>2=G*srTx`s8VE=cM+8bZ?pD$u@9T2i$dJ zd%1-SmySP#;FM`Id`!%RL7yMRHN?jy%$U`+9M9DZ)j&^y?WGygTRJXm`zst`sJ|&l zo4Ek?1T{-Sg$63C**gDAvyipNZF?}Tns+HU;O?i474N%!ceQ!;7Gz_aXEThVFs3<7 zhDmglTBmsOW@(JV3ogD8nx$oKj*%R~Rv zgoZYLZxvJxUTo-Icn#L+{wG6*kr;C!eyE~RAEj}NBja={`O*qr-!9+ex+(2K{?@*O zDs(CzCc#oVYjjwap=<#_(zs^=bBjjdq1OWc{O%sFRl{u?`VJ8`t081(__kId-#Zj= zKU$?r%$l2Beox{wTFkYvjlvToku6?-WoK@+D*8SoNGtl{X|JC0BGs4U-|@l0&!O0A zPY0o<2WnIKw#!2ThWg?-!JWmUjST|j7ei(iUVgrRZM?U)tu@Pquu2E3=OZP7qa7dZ zL33OhTPp1;$jQzPtgXIhdH#gJ?$3s9-|cK#$0f)+;!z*z4q-)%&}9AA?(5ctI~-G& z&t(UtnZ3#lTt1&C;y~QaM@b%q^nV=%v}Qqji>JA{x&v&1HLo@mj(l-dXS9y$?{0mS zX)^CLmJXjv;Nqea$KV8vXE;?#rB@qopI>Zd<&)FcTfvvcD@SALL7=0}_F8Er>?jiC zy&qg45O6+eoL^$up3#*XxO=YZ+&(@^l(Sj%yGe|Y?j~vKSeGF7_K@wVjCsaWD=+Pw zT6JOcV+letxa2D`SH zWi@=Mk0q6=R~tErk-1PSw!~ODLr+}49P7${5#qIsqr3j5O@eCWgD-K zhl%u3n|`-mx#;*CPp9C4;(1Ad_w|-0n^<*!?g;NYwz|ICce$z05evIF&ocHu^-M-7 zMA=`Lw<~!3m$YMD&x5QU!A|TQO7rr)Gt}=btysb6EPpp*wRz8*qTI#;4J}vcjhdd2 zqy08w!~lGOOP6Ky_+Pu{1$}NBijNx&HMzGwCwZuIQ?25R#YurPjX2MI5^u*Gsi~87 z2JCy35UAalY>mDQ=jI(k4(C|%#(MuwJO2H7(3reDybt!Y*jwK&TI@UL<9e{gGiAVL z#g5r&YnH?~-Pq%^;MKQEj75CLkZjRz3vwT8YjtWIk%qRHE8>T6m!32pU19d|yK|{( z)!^0Efa3>++u`4`?e;fXY@`-+suwJx@N5HK(cm>mJ6>4|T0M9Do|BZlDPi?wjqylq zj%urkooj7pe~Wy$|EYXur?0tXO2@?oJiN%q<=*F)4;J-DNz)#+7gv-?y@DDWPJD7q zUSyVL(cR|b8k{@yM{?D5jhgA5LjkLg>tBw!f7^2on^vAKapjA86X&s-M_U%m3+?S0 zlG`fQ=FF%Xax?ko=8DG)d!pav;o|P=m#d0GZtzjO?1;H# z(|a42jCHm;H3dtb#>XX3 z;QoW#=kkor*tB{PLeY%8A}Bvn{8hG~DELixXwaDKc|lHr-`l#YlRo{ep3;8*UCNpz zJ&!C#zrR|NsS&u}&h^rT=|>cEmH}T!*oC<#XR}VXdIlaGs!pi9k-FTtx4J33?{UW; z`q0Cmb7+02!S=b^)1K`=w?LIuGW+|w870VL*`F^S8(jMoTa@QHvrlH!@Z0aRx-+Z2 z6O(r>FkL^sR`E;RKS4@C|4cFzKe?Xh(($7YgZx232%Z~;u>rQ=Ww0-4aR(I?o z_JMQp*auCB(Fe9o`CYkf_L@rXL>uYa!naA6LQI#J`Nkk?DzgiMhItPIhyU?8(tdJB zh`~+RQQ?};rLe8b@5ri6jJ25wp*Nn77(cnAp*K~)QI8395J;0w`waG%6$E|eEh(Pd z1%ZXSNIFJmw`IyNo)KwnKUy?CuuZgR?vNYCY`vFfSGapeYM_&QSL@c@v*^?c*b63g z8uK}ehQ_)eMUq*Jd5>jsleP#;ZVTay6@qAorASW zefrx&?PsS2@3dPPm_K_FoeJNzoo_8>do@C$6Ui|*@AeIOa?Jk|Z+5fa9=j!ln*$R0 zV(vGH!jrdWB#tefU%pg7g;?pC-pF&ReDEgo)5)#1@>k#XZCgf<#IoROr?+hm{jQHN zGcneo(06T`edU9#F8)0SGCx(sz-7jNc*O}7ma{?LS7c`SEY`bHX_M3@yJ5wpz{QW2 z#Z(n9yLRv1?!%FB(ExVV^_a-6EmD$e!?D?2)A2pmr~Q4dPe9M>M3;nT{#M2EED0L+ z`RFyptny{_yVc=+musQ5&S$rk#Q@dw%PIK>5gK;$=zYbk3SIi${lc!4!uj1Pp@-i- zklhb@*KyrO=m)!7-PdSk=PQTVUUhQK%Z2kVn-6|AF%RA28(7t4xki{jgHGM}^`^3O z_C|a}H7`HDxOV&ZYbNI7pH1GbfV}^MmkwW;PoY!G`u=Mu<^2 z7>rq)c4=kVHX$S`VONiRQ_OmQ6-|nZgJ}2!jG2N*?oJuT?E_AW8Bxk_wR!1oJqS|4 zFW2EDuU}%H@o(s_2OOmhQ-i9FW=APMgm&8=Dw3Hvz-}8+4jpq39cgkZ+8;3XI%56v z^|g`8!=Pc-LqoL826KwXZ_DJLgOulC3_g>WuD3GS9YGF0I{Hsd#O_d8u9dCNAlRf1 zNq3KbvN|?gb|APnzGw-pK6ND(5u}Wqg8nA+id}_RbUdaPUPwizUJm**bhvSyaR___ zP@_{L+N+Qf7mcR=)FanTLW;?EpL&pzJBuH6J|2HGD~1ENXlrqa$Ai^~-_@zV2Y)@1 zEbC!JEA!|qL)#t|j;><^(c^|VOtwmsO`H5=yMibtrMSE5_ZzR? zhx8g>feX-6sPpXY`o49nW1o*jQO1{lMYGs6;&&U?V(cs$hX3jUN=0HF9{v*#t~y&R z;iK>^5-GPK+MS_&a}>r?VPQ~aVXma}Y@t6CK?-<8dlUQyWs5csT_fhgXHO(o1&6{* zM(~Lg@AYyjpf2E}P~Yi*PvhyvgaQ0(>PvkB%N%TVq@XMvI`uNZ_LH!$0rofvn**>= zMZ#fC0k(;RodU2ZfdyZA5p*>{<`$@4iNwuHVt}j`Vc;&HLT6xD@*3KICHm*%Ki=^s z`tOA+3YJO`z<=j6Eu0YdK-{LCBt`sfG$BGw5}6iDiul{Jgt!1INz={~q7)aC3DF*0 znCwLGIstaAG28|G$4XoyA{_8l9nm9U6`{S1P7DH+X%W3d0sx#nM3CJ8^#f-U+!=8+ zfJQICox#h)T=?VyfrSD9l0|Uk?F6Ka1X31U7}Mbs3k>Huh`@$5IFl=|Ig5M=P&FLX il!y@WfBZMxJ5Fhu`EUSvIOhv)YK`?;{%xK|`2PcsaC$QU diff --git a/third_party/test/golden_widget/flutter_logo.string.rtl.png b/third_party/test/golden_widget/flutter_logo.string.rtl.png index e65700f87fa6172382fd53a21970ffacf71e87d1..6c8dd292777c2640514e08b937b8d3d764a80b9e 100644 GIT binary patch literal 3490 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 YSB+27^+L(4GaIXiuXg~ihI=^kzdytZE&u=k From 15332b8c1bf9ac3310191e9139159f601452182b Mon Sep 17 00:00:00 2001 From: Aliaksandr Luferau Date: Tue, 21 Jun 2022 19:33:44 +0300 Subject: [PATCH 444/512] Added the flutter_lints to the development dependency for project 'example' (#723) Co-authored-by: aluferau --- third_party/example/pubspec.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/third_party/example/pubspec.yaml b/third_party/example/pubspec.yaml index 57954c786dee..f90020e36941 100644 --- a/third_party/example/pubspec.yaml +++ b/third_party/example/pubspec.yaml @@ -11,6 +11,9 @@ dependencies: flutter_svg: path: ../ +dev_dependencies: + flutter_lints: ^2.0.1 + # The following section is specific to Flutter. flutter: uses-material-design: true From 43a81ae375dfb8ffdd7217d2e4c35e7c08b75bb9 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 21 Jun 2022 10:46:28 -0700 Subject: [PATCH 445/512] Fix 720 (#724) * Fix 720 * use Object.hash --- third_party/lib/src/picture_provider.dart | 10 +++--- third_party/lib/src/svg/theme.dart | 2 +- third_party/lib/src/vector_drawable.dart | 4 +-- third_party/test/vector_drawable_test.dart | 37 ++++++++++++++++++++++ 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 783161c4271c..6273a233a46f 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -5,7 +5,7 @@ import 'dart:async'; import 'dart:typed_data'; import 'dart:ui' - show BlendMode, Color, ColorFilter, Locale, Rect, TextDirection, hashValues; + show BlendMode, Color, ColorFilter, Locale, Rect, TextDirection; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; @@ -157,7 +157,7 @@ class PictureConfiguration { @override int get hashCode => - hashValues(bundle, locale, viewBox, platform, colorFilter); + Object.hash(bundle, locale, viewBox, platform, colorFilter); @override String toString() { @@ -455,7 +455,7 @@ class PictureKey { } @override - int get hashCode => hashValues(keyData.hashCode, colorFilter, theme); + int get hashCode => Object.hash(keyData.hashCode, colorFilter, theme); @override String toString() => @@ -502,7 +502,7 @@ class AssetBundlePictureKey extends PictureKey { } @override - int get hashCode => hashValues(bundle, name, colorFilter, theme); + int get hashCode => Object.hash(bundle, name, colorFilter, theme); @override String toString() => @@ -582,7 +582,7 @@ class NetworkPictureKeyData { } @override - int get hashCode => hashValues(url, headers); + int get hashCode => Object.hash(url, headers); } /// Fetches the given URL from the network, associating it with the given scale. diff --git a/third_party/lib/src/svg/theme.dart b/third_party/lib/src/svg/theme.dart index f5cba20ead13..b33a5f9ee770 100644 --- a/third_party/lib/src/svg/theme.dart +++ b/third_party/lib/src/svg/theme.dart @@ -41,7 +41,7 @@ class SvgTheme { } @override - int get hashCode => hashValues(currentColor, fontSize, xHeight); + int get hashCode => Object.hash(currentColor, fontSize, xHeight); @override String toString() { diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 8be73efc60d2..0fdadbdd5d70 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -1288,12 +1288,12 @@ class DrawableShape implements DrawableStyleable { if (style.mask != null) { canvas.saveLayer(null, Paint()); } - if (style.fill?.color != null) { + if (style.fill?.style != null) { assert(style.fill!.style == PaintingStyle.fill); canvas.drawPath(path, style.fill!.toFlutterPaint()); } - if (style.stroke?.color != null) { + if (style.stroke?.style != null) { assert(style.stroke!.style == PaintingStyle.stroke); if (style.dashArray != null && !identical(style.dashArray, DrawableStyle.emptyDashArray)) { diff --git a/third_party/test/vector_drawable_test.dart b/third_party/test/vector_drawable_test.dart index c7efeb5bd7e0..03a854096d84 100644 --- a/third_party/test/vector_drawable_test.dart +++ b/third_party/test/vector_drawable_test.dart @@ -2,6 +2,7 @@ import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_svg/src/svg/parser_state.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { @@ -115,4 +116,40 @@ void main() { recorder.endRecording(); }); + + test('draws even if color is null', () async { + final DrawableShape shape = DrawableShape( + 'test', + Path()..addRect(const Rect.fromLTRB(0, 0, 50, 50)), + const DrawableStyle( + fill: DrawablePaint(PaintingStyle.fill), + stroke: DrawablePaint(PaintingStyle.stroke), + ), + ); + + final PathRecordingCanvas canvas = PathRecordingCanvas(); + shape.draw(canvas, Rect.largest); + + expect(canvas.paths.length, 2); + expect(canvas.paints.length, 2); + expect(canvas.paints.first.style, PaintingStyle.fill); + expect(canvas.paints.first.color, colorBlack); + expect(canvas.paints.last.style, PaintingStyle.stroke); + expect(canvas.paints.last.color, colorBlack); + }); +} + +class PathRecordingCanvas implements Canvas { + final List paths = []; + final List paints = []; + + @override + dynamic noSuchMethod(Invocation invocation) { + if (invocation.memberName == #drawPath) { + paths.add(invocation.positionalArguments.first as Path); + paints.add(invocation.positionalArguments.last as Paint); + return; + } + return super.noSuchMethod(invocation); + } } From 19bccf2ea84cc2e6e54d62707b6bdc4bdda8739f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 28 Jun 2022 09:59:12 -0700 Subject: [PATCH 446/512] version bumps --- third_party/CHANGELOG.md | 6 ++++++ third_party/pubspec.yaml | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 37e4bc32cda9..203bdebd8c57 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGES +## 1.1.1 + +- Fix a bug introduced in 1.1.0 related to fill/stroke inheritence. +- Explicit dev_dependency on flutter_lints +- Avoid deprecated API from Flutter. + ## 1.1.0 - Respect stroke* properties when a paint definition is used for a stroke. diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index e6df26dd60ed..595a99eaa244 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 1.1.0 +version: 1.1.1 dependencies: flutter: @@ -19,7 +19,7 @@ dev_dependencies: test: ^1.21.1 environment: - sdk: '>=2.17.0-0 <3.0.0' + sdk: '>=2.17.0 <3.0.0' flutter: ">=2.11.0-0.1.pre" ## For developing features that require new functionality in engine: From 7d886d4f0b933d3b29ff310e4ef24b4a808d6215 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 28 Jun 2022 11:16:47 -0700 Subject: [PATCH 447/512] fix whitespace, update simple example to be simpler --- third_party/example/lib/simple.dart | 30 +++++++++++++++++++++-- third_party/lib/src/svg/parser_state.dart | 2 +- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/third_party/example/lib/simple.dart b/third_party/example/lib/simple.dart index b51da3e64894..815f8d340f9d 100644 --- a/third_party/example/lib/simple.dart +++ b/third_party/example/lib/simple.dart @@ -1,12 +1,38 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +const String svgString = ''' + + + + + + + + + + + + + + + + + + + + +'''; + void main() { runApp(MaterialApp( home: Scaffold( body: Center( - child: SvgPicture.asset('assets/flutter_logo.svg', - width: 500, height: 500), + child: SvgPicture.string( + svgString, + width: 500, + height: 500, + ), ), ), )); diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index 3f6b43815716..c5d1da31cbe5 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -792,7 +792,7 @@ class SvgParserState { this.theme, this._key, this._warningsAsErrors, - ) + ) // ignore: unnecessary_null_comparison : assert(events != null), _eventIterator = events.iterator; From 353c2cfeaab36266f56b928d0a4a451cf81e5079 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 1 Jul 2022 20:10:06 -0700 Subject: [PATCH 448/512] Update currentColor handling. (#730) * Update currentColor handling. Default currentColor to black, mirroring Chrome's behavior. Update callsites to parseColor so that they account for currentColor. Avoid setting a default currentColor on the root element when parsing. Avoid painting when Paint.color == null. --- third_party/CHANGELOG.md | 6 ++++ third_party/lib/avd.dart | 2 +- third_party/lib/src/svg/parser_state.dart | 36 +++++++++++---------- third_party/lib/src/svg/theme.dart | 4 +-- third_party/lib/src/utilities/_http_io.dart | 2 +- third_party/lib/src/vector_drawable.dart | 4 +-- third_party/lib/svg.dart | 6 ++-- third_party/pubspec.yaml | 2 +- third_party/test/colors_svg_test.dart | 6 ++-- third_party/test/vector_drawable_test.dart | 11 ++----- 10 files changed, 42 insertions(+), 37 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 203bdebd8c57..4b8e15b2bd02 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGES +## 1.1.1+1 + +- Fix regression introduced in 1.1.1 +- Update fix for fill/stroke inheritence when currentColor is specified in the + SVG but not in the theme. + ## 1.1.1 - Fix a bug introduced in 1.1.0 related to fill/stroke inheritence. diff --git a/third_party/lib/avd.dart b/third_party/lib/avd.dart index bfd3f67ac9e7..2567ef7dfdd6 100644 --- a/third_party/lib/avd.dart +++ b/third_party/lib/avd.dart @@ -1,5 +1,5 @@ import 'dart:convert'; -import 'dart:typed_data'; +import 'dart:typed_data'; // ignore: unnecessary_import import 'dart:ui' show Picture; import 'package:flutter/foundation.dart'; diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index c5d1da31cbe5..975b726b6c09 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -87,11 +87,10 @@ class _Elements { final String? id = parserState.attribute('id', def: ''); - final Color? color = - parserState.parseColor(parserState.attribute('color', def: null)) ?? - // Fallback to the currentColor from theme if no color is defined - // on the root SVG element. - parserState.theme.currentColor; + final Color? color = parserState.parseColor( + parserState.attribute('color', def: null), + currentColor: parserState.theme.currentColor, + ); // TODO(dnfield): Support nested SVG elements. https://github.com/dnfield/flutter_svg/issues/132 if (parserState._root != null) { @@ -144,9 +143,10 @@ class _Elements { return null; } final DrawableParent parent = parserState.currentGroup!; - final Color? color = - parserState.parseColor(parserState.attribute('color', def: null)) ?? - parent.color; + final Color? color = parserState.parseColor( + parserState.attribute('color', def: null), + currentColor: parent.color ?? parserState.theme.currentColor) ?? + parent.color; final DrawableGroup group = DrawableGroup( parserState.attribute('id', def: ''), @@ -164,9 +164,10 @@ class _Elements { static Future? symbol( SvgParserState parserState, bool warningsAsErrors) { final DrawableParent parent = parserState.currentGroup!; - final Color? color = - parserState.parseColor(parserState.attribute('color', def: null)) ?? - parent.color; + final Color? color = parserState.parseColor( + parserState.attribute('color', def: null), + currentColor: parent.color ?? parserState.theme.currentColor) ?? + parent.color; final DrawableGroup group = DrawableGroup( parserState.attribute('id', def: ''), @@ -240,7 +241,8 @@ class _Elements { def: '1', )!; final Color stopColor = parserState.parseColor( - getAttribute(parserState.attributes, 'stop-color')) ?? + getAttribute(parserState.attributes, 'stop-color'), + currentColor: parent.color ?? parserState.theme.currentColor) ?? parent.color ?? colorBlack; colors.add(stopColor.withOpacity(parseDouble(rawOpacity)!)); @@ -1339,7 +1341,7 @@ class SvgParserState { ); strokeColor = definitionPaint.color; } else { - strokeColor = parseColor(rawStroke); + strokeColor = parseColor(rawStroke, currentColor: currentColor); } final DrawablePaint paint = DrawablePaint( @@ -1433,8 +1435,7 @@ class SvgParserState { Color? defaultFillColor, Color? currentColor, ) { - final Color? color = parseColor(rawFill) ?? - currentColor ?? + final Color? color = parseColor(rawFill, currentColor: currentColor) ?? parentFillColor ?? defaultFillColor; @@ -1634,6 +1635,7 @@ class SvgParserState { ), decorationColor: parseColor( getAttribute(attributes, 'text-decoration-color', def: null), + currentColor: currentColor, ), decorationStyle: parseTextDecorationStyle( getAttribute(attributes, 'text-decoration-style', def: null), @@ -1644,7 +1646,7 @@ class SvgParserState { } /// Converts a SVG Color String (either a # prefixed color string or a named color) to a [Color]. - Color? parseColor(String? colorString) { + Color? parseColor(String? colorString, {Color? currentColor}) { if (colorString == null || colorString.isEmpty) { return null; } @@ -1655,7 +1657,7 @@ class SvgParserState { if (colorString.toLowerCase() == 'currentcolor') { _compatibilityTester.usesCurrentColor = true; - return null; + return currentColor ?? theme.currentColor; } // handle hex colors e.g. #fff or #ffffff. This supports #RRGGBBAA diff --git a/third_party/lib/src/svg/theme.dart b/third_party/lib/src/svg/theme.dart index b33a5f9ee770..607f814e1aa1 100644 --- a/third_party/lib/src/svg/theme.dart +++ b/third_party/lib/src/svg/theme.dart @@ -10,14 +10,14 @@ class SvgTheme { /// /// Defaults the [fontSize] to 14. const SvgTheme({ - this.currentColor, + this.currentColor = const Color(0xFF000000), this.fontSize = 14, double? xHeight, }) : xHeight = xHeight ?? fontSize / 2; /// The default color applied to SVG elements that inherit the color property. /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword - final Color? currentColor; + final Color currentColor; /// The font size used when calculating em units of SVG elements. /// See: https://www.w3.org/TR/SVG11/coords.html#Units diff --git a/third_party/lib/src/utilities/_http_io.dart b/third_party/lib/src/utilities/_http_io.dart index fbc06cd22b03..458a20725ad2 100644 --- a/third_party/lib/src/utilities/_http_io.dart +++ b/third_party/lib/src/utilities/_http_io.dart @@ -1,5 +1,5 @@ import 'dart:io'; -import 'dart:typed_data'; +import 'dart:typed_data'; // ignore: unnecessary_import import 'package:flutter/foundation.dart'; diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 0fdadbdd5d70..8be73efc60d2 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -1288,12 +1288,12 @@ class DrawableShape implements DrawableStyleable { if (style.mask != null) { canvas.saveLayer(null, Paint()); } - if (style.fill?.style != null) { + if (style.fill?.color != null) { assert(style.fill!.style == PaintingStyle.fill); canvas.drawPath(path, style.fill!.toFlutterPaint()); } - if (style.stroke?.style != null) { + if (style.stroke?.color != null) { assert(style.stroke!.style == PaintingStyle.stroke); if (style.dashArray != null && !identical(style.dashArray, DrawableStyle.emptyDashArray)) { diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index cb607dbab3e1..d48ae3953925 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -1,6 +1,6 @@ import 'dart:async'; import 'dart:convert'; -import 'dart:typed_data'; +import 'dart:typed_data'; // ignore: unnecessary_import import 'dart:ui' show Picture; import 'package:flutter/foundation.dart'; @@ -780,8 +780,8 @@ class _SvgPictureState extends State { final SvgTheme? defaultSvgTheme = DefaultSvgTheme.of(context)?.theme; final TextStyle defaultTextStyle = DefaultTextStyle.of(context).style; - final Color? currentColor = - widget.theme?.currentColor ?? defaultSvgTheme?.currentColor; + final Color currentColor = + widget.theme?.currentColor ?? defaultSvgTheme?.currentColor ?? const Color(0xFF000000); final double fontSize = widget.theme?.fontSize ?? defaultSvgTheme?.fontSize ?? diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 595a99eaa244..4c5ce6236b0a 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 1.1.1 +version: 1.1.1+1 dependencies: flutter: diff --git a/third_party/test/colors_svg_test.dart b/third_party/test/colors_svg_test.dart index 4f93c26c367d..65aff31183e5 100644 --- a/third_party/test/colors_svg_test.dart +++ b/third_party/test/colors_svg_test.dart @@ -44,8 +44,10 @@ void main() { const Color(0xFF6F2173)); expect(testSvgParserState.parseColor('hsla(0,0%,100%, 0.0)'), const Color(0x00FFFFFF)); - expect(testSvgParserState.parseColor('currentColor'), null); - expect(testSvgParserState.parseColor('currentcolor'), null); + expect(testSvgParserState.parseColor('currentColor'), + testSvgParserState.theme.currentColor); + expect(testSvgParserState.parseColor('currentcolor'), + testSvgParserState.theme.currentColor); expect( () => testSvgParserState.parseColor('invalid name'), throwsStateError); }); diff --git a/third_party/test/vector_drawable_test.dart b/third_party/test/vector_drawable_test.dart index 03a854096d84..72a6adf2aec8 100644 --- a/third_party/test/vector_drawable_test.dart +++ b/third_party/test/vector_drawable_test.dart @@ -2,7 +2,6 @@ import 'dart:typed_data'; import 'dart:ui'; import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_svg/src/svg/parser_state.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { @@ -117,7 +116,7 @@ void main() { recorder.endRecording(); }); - test('draws even if color is null', () async { + test('Does not draw if color is null', () async { final DrawableShape shape = DrawableShape( 'test', Path()..addRect(const Rect.fromLTRB(0, 0, 50, 50)), @@ -130,12 +129,8 @@ void main() { final PathRecordingCanvas canvas = PathRecordingCanvas(); shape.draw(canvas, Rect.largest); - expect(canvas.paths.length, 2); - expect(canvas.paints.length, 2); - expect(canvas.paints.first.style, PaintingStyle.fill); - expect(canvas.paints.first.color, colorBlack); - expect(canvas.paints.last.style, PaintingStyle.stroke); - expect(canvas.paints.last.color, colorBlack); + expect(canvas.paths.length, 0); + expect(canvas.paints.length, 0); }); } From 0cd3cb881d46da3f3ab7bf9915c75063346809af Mon Sep 17 00:00:00 2001 From: matthewyan Date: Mon, 4 Jul 2022 15:36:36 +0800 Subject: [PATCH 449/512] format code (#554) --- third_party/example/lib/main.dart | 18 ++++++++++-------- third_party/lib/src/vector_drawable.dart | 13 +++++++------ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index 6a1cc8c06aa5..e8cf2283caf5 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -113,8 +113,9 @@ class _MyHomePageState extends State<_MyHomePage> { SvgPicture.network( uriName, placeholderBuilder: (BuildContext context) => Container( - padding: const EdgeInsets.all(30.0), - child: const CircularProgressIndicator()), + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator(), + ), ), ); } @@ -137,12 +138,13 @@ class _MyHomePageState extends State<_MyHomePage> { ), body: Column(children: [ Slider( - min: 5.0, - max: MediaQuery.of(context).size.width - 10.0, - value: _dimension, - onChanged: (double val) { - setState(() => _dimension = val); - }), + min: 5.0, + max: MediaQuery.of(context).size.width - 10.0, + value: _dimension, + onChanged: (double val) { + setState(() => _dimension = val); + }, + ), Expanded( child: GridView.extent( shrinkWrap: true, diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 8be73efc60d2..1ff13d6a6a12 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -1298,12 +1298,13 @@ class DrawableShape implements DrawableStyleable { if (style.dashArray != null && !identical(style.dashArray, DrawableStyle.emptyDashArray)) { canvas.drawPath( - dashPath( - path, - dashArray: style.dashArray!, - dashOffset: style.dashOffset, - ), - style.stroke!.toFlutterPaint()); + dashPath( + path, + dashArray: style.dashArray!, + dashOffset: style.dashOffset, + ), + style.stroke!.toFlutterPaint(), + ); } else { canvas.drawPath(path, style.stroke!.toFlutterPaint()); } From 7d29bed8ffc7490e94f0a890c5bbd3580026d956 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 6 Jul 2022 14:38:44 -0700 Subject: [PATCH 450/512] missing unused import --- third_party/lib/src/picture_provider.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index 6273a233a46f..bf46e3150bf2 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -3,7 +3,7 @@ // found in the LICENSE file. import 'dart:async'; -import 'dart:typed_data'; +import 'dart:typed_data'; // ignore: unnecessary_import import 'dart:ui' show BlendMode, Color, ColorFilter, Locale, Rect, TextDirection; From 509416f3c168bf9350bb34ac41695d389e634dae Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 3 Aug 2022 17:41:49 -0700 Subject: [PATCH 451/512] bump path_parsing --- third_party/CHANGELOG.md | 4 ++++ third_party/pubspec.yaml | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 4b8e15b2bd02..f47c07003684 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 1.1.2 + +- Update path parsing/drawing dependencies to fix arc parsing bug. + ## 1.1.1+1 - Fix regression introduced in 1.1.1 diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 4c5ce6236b0a..9e8b5d41d3d7 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,13 +1,13 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 1.1.1+1 +version: 1.1.2 dependencies: flutter: sdk: flutter meta: ^1.7.0 - path_drawing: ^1.0.0 + path_drawing: ^1.0.1 vector_math: ^2.1.2 xml: ^6.0.1 From 384c8eb960ce8ad66da3b03e34c39e2d425cfd56 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 3 Aug 2022 17:58:24 -0700 Subject: [PATCH 452/512] update goldens --- third_party/golden/svg_currentcolor.png | Bin 4234 -> 4192 bytes .../test/golden_widget/columns_and_rows.png | Bin 25764 -> 23184 bytes .../test/golden_widget/flutter_logo.asset.png | Bin 10330 -> 10130 bytes .../golden_widget/flutter_logo.memory.png | Bin 10330 -> 10130 bytes .../golden_widget/flutter_logo.network.png | Bin 10330 -> 10130 bytes ...go.string.color_filter.blendmode_color.png | Bin 9168 -> 9032 bytes .../flutter_logo.string.color_filter.png | Bin 7618 -> 7518 bytes .../golden_widget/flutter_logo.string.ltr.png | Bin 3404 -> 3411 bytes .../golden_widget/flutter_logo.string.png | Bin 10330 -> 10130 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 3490 -> 3496 bytes 10 files changed, 0 insertions(+), 0 deletions(-) diff --git a/third_party/golden/svg_currentcolor.png b/third_party/golden/svg_currentcolor.png index 47d93874deebc2b7ef8c7aec566ac79354514efd..5411bae167ed586b3c9762a7dccef763ffb8b9e5 100644 GIT binary patch literal 4192 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 diff --git a/third_party/test/golden_widget/columns_and_rows.png b/third_party/test/golden_widget/columns_and_rows.png index d4baaddf86b636c9e296dce515657b0d4ff1654e..34053145e281c2d6bf83eb6acc305fd547a1555f 100644 GIT binary patch literal 23184 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
t*%$@hS!C00^JF1i0X6&Mk*F7tCFiuKoiJG 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�u9vbX{zc#lGCFlb@L2Onwq@UnkgLn5^=% zq#Xhq0ygN~J|E3IgZ9Z6!6GA38Qy&x={-lvYAf4vcx1YTsVA>29T??*z4xUkKdm8q%vtBA2^6VZvVQ-BA>31|E4hdqm4U_cWzIOSyIwID|q1Ovt#_^)q-rI~H# z4PW$Q>v+BIjk^^f+lk-;&xsX|4Vc+)u)$u35dPbNeZfC=f%r$X^iV{i0IEZ-mJ03BuXz>Th*$6!z7{9k;j`}z z-wFT?FzZj?;U=Qx4t06&dBW;Cxwe5x)4|&ckn8jU)8JQt+f612bM&|mno&f{nmJ^{ zZs<{>Q=@M*U!JcfoM(tiCK5-9*Wgc%ZSx4K*0?vJM>&uxeCG~+GEoWW=&SHztZ>J>{Y++XZyIj= z)z8!y7=;tFTGYLwuXlQBf+;?R1G$)c;MyAul*kk8j$UEGdqaVnulOgu*t0^>!xV6R zeyKCOe{Or^8V{zV0uBQwfdrHn799LLFZ^PKONZ<+yzz@LkRb^mLxi0Oj%+P>xRIzG zf2E|On(XuYuj;t!5{pE$lTrGQ;d7#{j2`3Ht``!gqb8E13BoN%l<#$V9VDYB^^1f#(C)hyfw6zZEVvng1pS9wAUDhsN`-^Z z?~FiDIBvYUFlK}^NiqZ2?>R4b4p9DQD%STdY6ag>w8YIRDL7q_mNpNjh&bawCVuaU4Ej+!u)tT*Cj_ zpA0rVj=U^z{4wSa@Pn{7N-C4M^yfC8cmD?wRfi~fIHxJN1z9}Y4dbP`D?8Q`rN{$FW(ljFeUmH zlGF3m@cf^X*ooMG4BrMPJbTNC5#&yA%I(sFf4tHEe8S@Z$^vMAk9~{bP!te z4AultnjK~1$P7YpeCV)|TDX0_Z`7!2Pg5)6NKr-9OK)3JZ4ryiGn6HxcEK5b&$yBDjkyhq&T#lnZ8>er5xpSYB4(Rs z0Jh8l+$io^!whb0#GR}UeG_E6hNJ03@`4|bRt)k)v%UXl(PY$SobY&1!G422wqgwH z%f8hHzT(Z(Bz;&>eYL^WEn@gQ!y$M&m=?mdhRFizR4mY(B{HU4G!*%Y^V$abs*D~% z!GBWcW}?c*wW6U~bCMQ9k}qF#jHWSF8X`e{k#om%UJ#fSgsVQ@7O~Jg15k;xQ(3~< z2aWp6)NKV0&NHWh8MdY&$8ON|SK(~0eQ)5^3UwlE*45$R=Adhk=8ulTfHc27&0lGL z#r%?u)HvbT`>y&|wulMl86uNWFDHwHvk&JO0R(+ATGYjP%{+|XkGbtlkDYSUa4$Vr zuto)V-y>HUzx{?gz=}GiqndeXPeV6U_8@fg6aOT1^K%ah-E^4>httV}Hjm+b;;u5D z`wcwvdK`{GvGLLd+Ca#vLIVBDhT)(ulM<`&NIMIzP##im+0{N zKJ_D|>Xa%_7W+@CKmcoJ{n}&r-UC-^pxN0@zC;gl(E@m7u0>!M3=&@`WYCW@_m&YA zYjt%i(@!_r3FE1@tOPp|<-p$uP6s~p#fyoTzNxP9UsAbP>Vl55@%?;PQX?V$>le zK*fcCywX>Ri{hm9h@RW8O$4F6`lq|iaMPZ^JJ&4^WmL7H&Ztw%Zk*~59FR*}uj%F) zy!U@x+9DQn4FfJ@fVh1WxwZrE`KhrvkcZl=ccapx)sQ3La~I|)urHyI->yToR(%k zztCL8r;lSBh1GJ-;(J`4r%(Z)igllTKFX~C?aumk;B7Vms1SSWQX_LcCS;qIafzcmmk|6(ueYz*5Q( zw_Al$V05b_QOF?cUzjbO^r+_j3Ff-J&TIK1K{Wf#{<&CTXn9T%1Q7X?ZpgiDHf?<# zqFM`|-mI>=E407#B{?0zbqcosAm>vQeS)7!ziBG=Q32dE0r@8~+x5gwxx#0Z65rCkW0C4+IA?gV-*h9m!MiYAu z@8}(e_PdQzxR;{D2OV1ujwkHaf}^<#m|I+CqK+Z~JEG9?Gw=I5f3qVh^iP(F0)Rr^ zc|ERqh7ll<;AlhOZV@cEA& z5gdn4kQ@RRf8P4tNcVf`WFlbHPQf68dfZt~wKc7iFe4X)(CqlNvLrg3tSv{KE6;rU z!?xHm`yID(6D3I|0?`*Na1gU!D}-=ST>L!0tf_F5L{&u8_3am7S_QaHGLb|lf@1#R ztA$d?w{e$&n5q9;TE+hywfZ+BBcdwat#VZ4=~3B*cgF%B-o0brD*bjGCXjWOr&FTh%U*B5L2G=)d$v1@*^ao_wnyiK$K|9H8?EoN7D(2y&-()YfdC?> zfste7+Jt~d<+19nebjN-EWJP6oKB?f0kRi?6o@~nTR6GNU|D_g zpkt6Ui9CEblJOKD>~3E6<6p1RlGVA_`fG@JqIdF!sb|;n3$%8z$8RpB=ME2Q6Lm*c zSM(ml7^{KXZFTaKgVie!eepnqH@AJ!2DV~6%>>c0S49msSmaLj}93|#>f z-Ku@D()-%#*)ad?p>zN0nW^7=l=pY79_bByAIfV9!l{!yDyy@Tj}cjvTt72aA1b9T zr1A4vSUl+-)|GW^68Rfw6v)*&Q z3jLa{6+!I>W`NJ~{@O=I>d*L80$~svXMeIuXs$^J_;d4739;#2((msmX$8PnLEZp? ztYHc!Xcz*jlh-N0=1ZDU%0y(vo@UCRK;K9Y2!cTr4M6VNDlTXrC2_`_QeuX`q6eAs zl-7=@xzKAzpKB@!dZp5mcibxCgDDYt<2-{|CFn30!&r?#Ejjp+dID3+QZ#0Tnr5xE ztR3w;rTEQ*QMQ3-_hbm;q2F*P(F7I-d~%kHPvQa3`IxX;cVTn)cv=P#vDb2+3Vj#8-ittw}4Jrw2e$YsX3@0n4{3rkn^ue>Z8HfX;@LG z%^jN6HW?Yss+ubMN9FX>yL*jrZ15)Il%|+{mBrZOjm|Glc z^g&zdZ9Z=tuzco12eKyisY~fL&U*6plyhqLo^daW$Ns61nC)Z)ylA&_txZ4u&nAG4 z=sR4gIOfB8x2)>wOZqdj9Ch?pIvfv}jfEt^=Y8Hz9n@RLN2AB9Hw zoDYEC1#}MtlCioEcTz4cNn;0L!RQ&Z(GnX)AQl#i?r7Qo5u7sft)HA3dfZpjsZYa{ zwZ5M9fW-zrk-y z(1^gg&0hB{izx4Li7v+IW=A)qtyXdARN56CfvD;zABbNh^sZ;;#(QYnus|MGt(BX0 zBJ~m=P#8Ga)Q!LK1!3jQ4KxC;5jY5dipE2s$8YQvdvJ(*uu!Y-QLUdeeyz+Qa}xB3 zV1rmtE zW95_aMDS+_ZrmxlyYwux+7V=Wkdt1AQ!?1=)da0vv?hRqwr;>{^G>2kyvhR1@ZwYu3TpE2BtI1|zbH8V-to-2>zjhN6D z4o`$lXLJjz_r?Yc(xRtm+&vnI)~iu~eFVhHe!cpALLqu~j>*k{5M?g8KeghB6Pmxu zH(MD<&Y0#;6$*%6`*WercH}>Gs&&ufqb$hE)?_pssB>-A_uWFv+H_xaQcSidufCL( z7SWJ1bht=he+RkeJe=Q_F%*nkR~gb1q33A&$0G~Y8P;(1J3XxnAM`qLNDhL+gPHRK z&q1}#=1j#okq@EdaXg=^uYCaIp3LX$AU4}}Ilq!tOmHb3`hCO_nKRp^9AVEvgkNL()lC^skiHgBZLU|D`lz1ihx z5&3d`uX>^)ix>a*YG4|O3N{!5aPAv{R|S?BM+PkS_)v;$T-8MT z)s^Bp#+WV(>6ruH*c9A#3i=oqBjh)Qg@gXAHIAF)7q!I<*3oSBZgJLR{&1RgJvfwO zCIpL-KJB%2Qv1cEjazUTM94PWqGDDlC`suZi?T8yQW>XqiQqTOY!*|5ai^+*Y_BJ~ z#TfhMtjul#ug?8QZm^n@czZezkp6JwooTNwT>akHk;+FP#=djq)(v(+V`4J;0^V#Y z`Z&LzliY%yRSy`6LRH@imAFyRIPygpag=V>S#;)eGdB=%LJLU;a@!(3>(%Pm9P`-2 z-)AzYwx~S4=P0}6d7bL0lCwvF?Wxjxt3VgnCCvh=P3jg7yn6U%K+jroktPgHvgh{L zDfg@>pb2gVz-dCEt}fesV3O}yq)AW;gg9y>eey@&zP}LA2vr?43bSx`;+J+fDHO`O zYl`Ve?IWzHnGU^IY+uK7HpFg4jZcy>8m*C0A3-8OiJ9Msxb!x`w zdVSX((iDT>_2MOcQMp85O>s0YI7U2O8Mrq)4d~Y4eB-i6YWQA2Ge^-!jKuTTinMbW z?=q|+Ter5tue(!JR>w_q+gq{rxBFJmzMCtmZ_RElcjX*@-j-Z?QY9am=vp7!M>C7| z9rc@zHwT22ebJZmwY5VCcrJ z$yId82^*=uPNR~fFRV*U)@<~gKekAz@hH+K4)FI1^#Z0DhV3b*lQvy!qp!7CnMLue zsKz@Q24TW3o;pR6QwURnh9%!JQAC;2Sn<$AKfhUddq*yvou=yQT20`@`GG8n3F4K^ zQD+;^Yb_H{CLws(G-+e~!a4)xBpx_xVT=LrEG}A|BuTeN2q*dqehV%3@?M!9hE3ta zyuE<;rZ@d87Hk^0hdtTt`T#M~!B-@y6~$&+Pj42g;ty}9hb-U^w)YtC1gxSm;%B$= z<*a%bg{F;e!WRKnm=oJF=>2CG0`^kT1z8XU3jfj^>yA81`_0w<%Ginc)`ll+$~D7o;GpR z6fxKj*NGaPeF_T0rXxW?*K*+23lYoBZyMt*-3shx)+Q{oB^eLC@&chq94~u(~SJI9vLNF9#nPc=_o1D(@{6t1TRDT4t3|8X-Hv@R+-GAQ<=;R=1w_Fg z%sBuaz)h>ejDvdU6Kzy$X{%?|lc}`!soqGul`AowrjIM_yPz(&Q; z%zq!*3z$s6$&?)2BUZy+FC;C!_bw7|qWu<*d>rop_Kf*m?xiQ0a!>(Ox{zFZZnSxn zZW8^SL|fgmxo&>C065R-Qjyyu#k$?OTr}I|-kGeA>ua$O@~i8pE1dV=jn|8Mo>X-M zZP#0oW{0(>qr#t0I_V`lr^?ho6gl3ClAr|I=aP#f3G<^=jC`7Z{ML;5wY1fYWMCCK zG6%iun&w8Wk7N5LxdhN>v4YJP_PoBq>PS0NR%=WJ(Eh3#erjE zT^|KAGNrP+t;(cp=v3t^ozyP7@bY^EARv0DEXxcm#{0v8l7?JIazmt82MEkdjcq!D z^!2DhDuI`u@}kWf=2>YT5{Q9mbSH3J8=--IRzby!&hJg2YCm}{v{ODO&n;BuyqZ{b zkpKPGf%Ij4e%mIwM}V!n_>-6gT`cKP)3ya#Knz3(;y{nHJ|8lsE?d)PGrzWGH}d{U z*AaT=GM27~(MS7Y^RwPYL;46b;W1Ai^rXMqJ-@614Re>5Z1Cm_uapC~zV4M??LbXYA+*$AQ zNzxND>lBgQvUWU65=xJQAeQZ_wd2P|)Ff!L#zp)2HV(`%ehyb_9UC@Ctb(lRaEB$5 z`&9aIl{yf@s{H@3LdPn^{b5km;2q5sA{c^BBoGJ{8Kpl7rzZ0uO2AyO_Ux)NrtR?F zaZh0ui3IN6Yc4vGY_C5wm|Hv>nyV%i0!oj$>v7L?za-0f*gCe+1EfBv z($Q65g&(bi%W*UXAda%O+i+loz{~&^p#~uF`s^=`J@q*m!#^0S(kv!qRQNE=iWL z(d>~$7J6VBc*CuOxPNm2fHDLFU?lK9ro10oGRvaoLW=2sr^XwttE+y$D3>022bE-W62jie);y6aN|3W)h{q04@udDrIQ=R3YC3FH^&3=ljdfm}-Li_qC_ zg))c|Qm)&p+084jY6Q#^qb{I%1a3`wfw~Idi|^Kk!`q*|F(}kR+jvmL>di};aGIOl z#3Z$wq+ZF|Kw0Hc558nd5w34dG)pwgGK!2MS+5p8wIbuq(D_#9F3cM3FLekv?|i0a zY50&1M}8>6ub7TMG46i)XJI%;THK;(T~h@ssMa*g2QJw^&b3B~3>)EiM9XeiMw7LP zo{nI4qu(Rbj!e0*5HDML;l!m(Y2GhHfQ_4=qXE=eu&3=COeXU(#(U9%Lx=}O%0LsW zmARmuO!k@o8&Lhxr^@V3lyGP%0~3Dvmd%<*`h>5~!bvCFr#R|Vn}zX^&1fhbF7eHN z)_JBWph)M~G+B{5KFCAm^Skb|q(o~syxT~oHJ89{4tJC8w;q-OdadCou`8!m)bM8= zJq`Kst=&BPkimh+5*_n>ilZi`EU|`^O6cB_AGzt-IakZVSC0WOo+b~OLd4wJ7{ZBlxp(?nhJAe>LyQJY z`o&A$K(yjhs}0O1cd9b$S*;gb6-~Z+3Mre-h}+1;RnTHs^_gP`NW^_IV#(+k(qc+K zX7)3!Gg=GYdt{wH^wQZrPQ(;ql685@X*HvC9i?#0yl0b6T6)9jtGeZ~Bq=h{ zy=3=IoT@_DTo?*dNJGndrp5CWnyfGFoGp3EZinsi9 zWm|3H$Lq2Os4g@*e~LM7NUTvvy%`3TyUt>u8QH5b-7xGQ21%#U!ZN!|z0>4~qZki_dV(-6w znh@)C-jEhVmcx_&#wSi4@c7Nyu3u7V6nr0^{xb(BeH&EL$_bYUeKfjuQLtv z)WB%kvG^r)Y}7Sd*xu4aWH7GG{`9iIYg^KCsr0M0(qyOJ(?}+>(Yxn5@NeHV-3(rS z?b&LRMk>X`g@MN`Y$Q=g@tvDcc`u(XI~t6NFI^B{>);uyvtFb)RMD&=v8YO2KhC_N zcT;v?6qI+|02>LWs;#(3yr6t@(YqFftp3362j^+#?Q<=RXeD?@f^@8%VohJ8sox86 zd>D}5WQvhl*p#V<_}ovOhIzW!d=Xqk^d~(5kM^o220VCO-*C#{uY7ssxv#e5K8&7bh`FNx}Y*P+p&Ipg|FBMQ1(PzOot!46h^$6`R+$&T0aibs|DFr z)>Gkof$_QUc4~SNKNLpdMffvuBzVQcEq@!N>OB!Rkfe0DefX1e_}Lt91@mD$Z)Ju` zQwPY|ZIj=;0c95{&EI|=nVL;(L?QKty@yMUhi4PJVh#sJ{oYM>ouzx#TT4D2wQ91Z z_`;6s`uYUlKVTb?3Hdp*%h910bixsm`TvYpG6LMr>mrLpq$248l0ltpDr8v zT4e)w;R%JxYzfN>5r`BZXGsy3HXE5fY|Y#t6&=5R9s!KDpE%N?0aXn>p)DAb+3kK2 z^&^bu%?i(~9O7O5K~ut$5gGoUcyx&8RTmg7s_Zhei{oxN%5$@8+Hs=KX9NhIAE;DM zCVNnj1Z{HyzVkSh=$9ydlgGDmvE|by3)!jA`c5$}xo?J@asU;sneK}k;+qf>J_7{`} z_-1cxMiolXe%i=E3H6=;NieC%9`jk(N(-=e^+RIZfl+@5$&~X?e z=H*ACrIviA&d-Wto+_~PU=O7U$va{L|lv?4wn8q|VwlR7bJZ|(YN5QGwcfee#RAY5bE04?pa9qb*Zr*cOsc|T)m8B zpL#*?s;5M+0tnVI;3su5m$eI!#MRNumtML>l`$8bT~K|`*z3W16$8pp7<00-UKo%Q zfrRE+BM}o}3ka;`P|XY88)@W7#L&PddJXW@piMAUfC*3j)g9fsgbOuN(~` z8}U1UgikdKD{nFWj#dE|rC_}}oV6PyJ%l4tpn8Lol_4P&e@WqCBUjIR!^f@+NKjbum}Trl(j}W^04)&CR7w;RM?+jlLrv4)_#j zt_zNOsk_Z2Whob+8f{h_?vVafcV8EUZzLiCg8KsG@-vGo&%rA)0=_kAAVf?`)rUvE z{#d(c&zEuhJyv+{m3-Sk<;mS3)@nDtcGcoAb7?TYAc|r}lk|5b!&AGPexLyBuW-6t zMi!upxNTcBfz&D@of;3NWg|6=tGDo}C#}wkBo0(J+m!{cKQk!}?aK`CZuK?Dh=b=@ z(>ZRen?F>n9(ZXQ6&R5;F<|+3LBAst0o8jh)fCb#w<99N%ClyhQif&=bH{~BuwMdM zwzs3FfEzIIzSaVv&2M!{ARN?aK7Rn24hiww`7iKP`~-ZFFa0IFs>RmN=u3aec(#HsEn(c@A*$2b-rdDF^Y`$`G z(`esEYFK@a@~yQfGpohCHmkLwStxwWI$IxFrJd;&M0XM$dJCLlQt(~@->F+esv%I7 zbXhyqRmO*$QSC|J!D|vUM{ZKv0$8QX`%U#Oa{yB=jG3HYuusN)^-Jbtj7am>1M&CRewA9%68Q!eH0gEvk?5)DMo zie2s(H8Y$&TtSUZ{|mQCqs}<7tTWV4VpuVDdxiIZMeF!OnZc7+8cdjR$-LliFZWMY zAJ#T30zZPpERpT=zYY0WO(I!TA-9Es_?g6bcjRDSu01ns@*xW*OD z+bQ6MWFR-AZR%G}!gL4NXoxK#VAxkFLwVvEgDj{E$bw$HCivhNNCKa{Iw5a(vHtQ+ z{4VegwMS_z4#!QmUh$?yA0j6Xw>vF*-v5>U#|9-tApQTXjWjp=@gzx6+eP&%ZN!^&;H ztwMt4j=}G$vUsSI$kH`adYt|gzxZxwSuib;vauKM{3&lB>^E<~{qMIlZ0Viw23|9S z-g@$#kj;MWsAMRZreNO~yet9y%f;>ALkhhFuV->s)9Te`GUmkT`quGI&4Q{@PHg{o zs!8Tfdmi#G1!g7iDD(*HN*`Bmo>1oADt$R$w_-o|}Djo8*;IpJLX<26O#`)_jR|NomJ zBC1APO+4bsbw2?P$kH;%vcI+~#^%o7A>a8w&0Tj`Q(4o8Wz}63v!ap(B(Ne@0-}^y z0xC`VTG0>$1wlkQ!csz!#i$?=5a~pUA|Rlo&;lxv8d_)}(nLTAy(FQB?*_m3C5iie z@4qj9T<&w9Gw00x&D=S2&Y79GX6Jd%O*I1ESxC`JSr#`epy)+3;!K;{89)bebQ<@5 zBSY)Z=CPoHBQj1mG`h-rq2!;*m=f8Y!T*x>1jppgi#Ugm*cX1Moz`2s7_bayDD9%}F8#caGnX~rlSGgfX< zwn%LM$BxRbN^+Axuy5{x;N*@0ss!WXg{fj`Y-F8Sb8lkhMP+#UDJ`@TG`gk@XCk@R;uz zG$*(JJA=mk`_c5vJMozEEeQTQQh{9Ech66n^O;Lu6(c5!`#_w zqEl=(=Y-c!1H2C)cC9K2sFk!hjHrm)b3-E*lpvrYq4f&~R?w^VBbr7tV6OG8v3y{; z%C1lK7>dNte%`xkknedt3WAL=5Mk7rOf7Zx>IbY?E-upS9>*^w+2onq0G)RJ*lFzW zRv?i51yDFJjQ0MX;dSslP~fkETi}l-9iJPW{rn}6uqsyK{dfTuw(u4s0M#eB%zh1# zqj!#SlWmj?m26E&$cDwC-UtrI(qOgzFvE+zEg-KmhBF(L%<1ffUYl%<1AQZJ5Kuw+ zi3QksZZ|-Ui}!w7i+SP5JTMxN*|TFOKaLJW9uWH$yx{VyfZ{)L*9h+p42ur~VhvXP z&X3T&Lw!?ybS7sTJV@%s5F6aNSP)2n2CxKTG{4>1++-Z=@+~vKqnQNa2`ofn)J=!V z_YXR+X6CI?Zy^mnKb2p8K?Cz&evC66|Dy5 zG_2FlSTf6_y=3FIon#3^f2o)yk#~yGb`0`O z>d%@v#&$N2h$I)Noerj^NoxxnzkaFvY&{0OI@txw2YIEGVUC*8^5rRA@5-)=u~PqT7@B&(-B zR}~TE3=pZUw_m$!VLt@;o(;f_=Aj;sc4G@wA;jVM$coSMGZW0%CzeajLLrta zC(R3DB)+OiC?9oL@{?+f)rnlfZuP(>IrChC$M?2yzP9OlE;GUX)yJ!s42^>A?>sM8 zm2Mr0o&5#oV}s$vcsNB~AG0JZB18M~6 zF!FhGI$DNzJU~A(SijWOd5e9ZQTh@@BXT`87E_;Ju`3jYFR!D%c6U5S4;I+04Y#2GBxTWmrRoiJL;?p4$S{9hDc1g*%I}U3l^GLSJd8d?}S#DSA-(3x~8DH zj4`dRSAQk%buhw=2`K2NoOkX*+;G-Fg`K*M+TZ+P0rB!UgQWqio;mZqi01l7wRVSu z?*XOk_=KerobD;iJl*+&j9gh?#Mivho+E)=r*!Ip@LJlo`k5lw^2aY)d#c-q5qZ(> zx|jtCi%~b~u(BR6HeW}!w>}SkXL;6BmsX5u0HC(>$Z?9#k)l0eX*hxPp zUq1RcO|k^>2?b`P@>`Kdqvu~k(UU+qI}`suS3dTJK(nZ-ieR$zQ%-LSS?LD}2F2+R zUm958+O(W$M3*a|w2Ys&s=fFpjkUE^t*Q|MPu>c+5n4+iCbUIaZuXhi5imEoX!lKf zCqREl=Mu)9LGe_wy1v7P5>$(-xnuynNPG zjTy8|ZzKDwc!Yzog@Y+bP<2d3T?2%?Z@`P8th(!JU_v!u4iLUR^Jn;3b3=K#%9-;j6kuQU zeYT3qzV|&LIWSXT6k`7xPbTbUJ+`i28jeURg!FSjp%6OXmz)lNu<_|AcJ*IlZveyN>?ZYKlsX-@7GSDF>$`1{}@%9W% zBys87>Eq4Dh|IUGswMdeJsT9`50_Any;5(#pMuNmZ<0d^uph;A5qC2_6vOs5A5c;3 z*+O%=6v^=G@?t1U3kX8r7q;nX{T(awaQ8^dtXX2U{{4vm>AiRZ*FUmejNR)+9{1T0&{K(ZAix^r^%j*1(|F!kK$d**h& z3W7`vFxWg6@t2VDmbB%sXRQKy#}Rh(;zc1(#K37t72lP?=1Y3z@;aCU0{VdWHBt$T z4FNHhN2q>xpG9looFU4i4V+U?@fXzngsSd=kVUuIm2Hu;=L+ytIc@$AG4e9z(Wc*U z)8`=zSbAD-0t$DxU4NnM)UIeEosck*v5MljF{!~21723;DUgezvbOzc3eq8+Dsv5S zr~s#|(a3xDnqkv#`zust=Ld(=^q6+cDL!W+e?plhbkkF8P_tJ@rnP3SE}7(TWh@?L z<~>#LT8PE;0)8^!5cf9%024Um6u07|zTB(E)g_u`a-))-4BVuN-)K&^$3}L)fBge}R*NoKdV*xDrg{+u&CUrow%9NCDhcM7CN$#g!bD`%_|c9)u9xwW9ctZ!Qb%(Q*=!xU4yR4JTcxe5})+xzS%-^onA9+jCQKZ=9qP z)G>F%m4k!gPNPbW0`d)Qw|Cf@iXCgCbEXVYQxc# z?#6!;ymklI%i8<9tZfV5T8mmxy2i#>_e_;jI*$&YplVQWY&-Xtec{4M^-8+uHtc9q zw*AgoJO9cb4NU#O670AA519u1K%NLWyXkjs5>=;rs-g3?Of=)~o`4+{{SHT*1|8f} z{j0uMylB_XHL0z==fBJT^S$Qa{rVJO^?&&%e%&8TL0;Zi9@4hEIR05@^FZ)i!;Ce> zgCz%={9KzaQ1)R=WP`mBJ1bB3qtZkRqm+3nj1627;yhQj%C;rK4#kk0Y!13c=uD?j zxu&IxtSIG$+FT?nT+Y;ytvW$Nkup_=Scj99h)~kKTOuT-iZfN2h#Coc2te5cD3gom z#o>J@`tt$lR|3fle|wU6YYa%%7>@J-rBF*g5S{WR2*u+iq3UKQLJZvqd@XwrfgG4h zu?5kL5O488)FVX)5H(5B8bp*79YqM1N*J3%XCh)<+^v#lVE0$j*i7I>!tTXYV+qyG z5CI+?=f#`@?Ifz#d@h2n!ow!&g8q+*2&B&hXLk@#FK2`50fM*pIf#n}L7-r*2zj{z zkE?THzJBv`VQV0*rRG7$2GA;m`?m{9tiI5Gp1kyqj z6a7UZO{Y+u>4aN1Ap#4@xE`jV+(`tJECAIbLF)i?5((-Hpw0y71^`tfKoMM%oDE$N zph<+&B7M-r2u(u)XmWA$h&rq%g$4KsBKE+9LV$`qK@1~;B2vZQlHyGKEr~T#3Eq;T zDgKsN2O?AaEh$ciw;u@F9;>M|rXk^0eKD$r=J# z1p*a?mA)6|1q3-9oY_kDFQK6&CkZZ0GYU1IB%q0as7v(HguNtxGAUvpvPn@BL@FsV zDOA4+Q4hpv7YppF5vqET2&JAJ@e{zCn7POl9j@pz z8LcZc)Y+8OyogY4&L`%^2~{Td92r6?m6k=$tqpL3Y$PW^G>WCqCc@%8i$dK%>@>(i z0Bs>buK}nD0h$G%(In_O0F5U=!T&@75h`1KB`lqs4J8x`RgG9~$VC=c#3md;1Ssb5 zmFOgbz1+~7Fk0e5rD-lA@ISbL2pc`@Ss(ZyY7wHxd=N?hJ$8afM$N+jL>j5Ek4i(G z2nzKOARe&}kY&1DQ9fxb7sc@N17JP&fGWwh93pUq_bOFp36C7c4@%evl;n+4X%|UeYO6(vBB^>6cwf`uz#f9A!5-EUaj{g98&5+w zkRIxtN5Y~>d}~#vvp$J*luBC&ePD;%uu8<;Nh0~8SXLzAmNT59=g7F;)aIsBNw?3@ zP&E=X3qZq3(2W49M}i)w(x#B0aDb?hv%w<`G)bo&=uBtQ5zz|JBxggu2nh=#Czcye zR3ailwN{HtxTKiE6_p^Qcnic566=;N=uU{MKzBl11G=QRmn-7>5wwvxDol(VtrB$_ zN+Z`ILf-F^KVj?0e+^ICQ-+`Do>9BZ?lg_?m zQ>d22l1IFgkg$0qfdC*NB>~LY-1OBXm$@p;m*jCKidDioCSa9mXu$;R0xE6G1gtiN zYCytv0IWI*O9QgTBv~d6^&(ZVNF>aGv=vTgO2SC8Tq^B<6YYsen88GUU9QIjmnTYC zJxQPhK{2-kqE`tQ#0XLpff!GUB_I;8@nx4d!{3+O*z;!0vH1<9_L<|ucjL{8pEopX zAk{=XH$Upkcro7F)6=7voLDs&Y+z_DbT-julDo3@=?J-IT$y70`_YmEjbFbE7opw> zNZ5RwecYl_#Z^(tH zxmiT!OWLMPMX{U2ye5s6s8Ge^X1_U7Ib4O|H;uxp{!e$aFyso64GYv;BGOA0VS+mo z`{{)BO(vg5s0bk5#TYPeJ*L}m_0F%uo?;9VFJBk%_$Xwq6VDV1PX^EQAI~fbZzdnT z{Ih)$g=Y%SKilVnJA4#URIso=@imPQ+3H5|9n{Vo8h~&qN`& ztDvD9Ratu-g`~Uq@~DGnhab=OFckEslS?PuD}Y7Ip+EiW=d**TM2-G5>c=xInG!Af zQ2jH>^rg%n-h`_%CGqGiCHDsfy9%bqa z3p8qbdRCSxK8aM;gP^2FN*sPP9H~kfx+gpOJyvFBSwHx#gd?L&S~_X!@m=Px)j>y5 z7GLx40AslGXbR`GN$0o6J2daBGMpiYqeM!kgJtznsTjTD)S@s2qKDG&PL{=&8Oe-T zyp9OD=&2Hh^2N8fLa#eKp+hA0P=}KanOHcTC507oi_TDGix)>KXMrOkemS*8`}Fh{ zPoDUtu8cC1&cqVYBsS-6J)5J;NB3b2JV^_SlIU=jKF9E$DW!@VY~c{uD1eZ&J#hnv zKue!ORdC)Z25ws-<6t%}12ve(+zm5XU_iYU4CE`xD3He)GB@&}>(vPPMT~W8wGg4w zPG0XoVg3YY;s!QGD#O9e^^ioL!DR8)%D7u*v2p~mbj_@*Y`)N|ny{))XOzH2P+=1v zw@Sq$@@ujjiN%4Ztl-R>Ql_fUZ$U81)2Bt_;EbN^}&$y^-mh<&0a<^n;K{ zmPRS#8RHanHV?*g5>8J4v>bV@%T4!tY=gT`klTqdN^Bq}Nxy*muZENJsxMW{hYQEK z4iloQ6uQoWq1kIK;#!+W;eJiR37@nU!gZJFoU}MB2XJB;ThwsFveC@RyT0JK|}Lj&9Ume*KDglUv|e* z79WE?$5ru5l`5klN@7u}`117Sq9sVWS4+msH>Qrm*JNhFw|#01g54`1HA-I&x3>8$ z85`MN{w)f4A;CLL-XTUer^%7y3%HQ9FfOaGa#R^yNE(^ivg)byLrY~8F_bKp(ix9c zSbs+;<9RM53+O7b)_jf#?*Ap{O9guDHi;bJk+(Az33=1>?5UuIyS6TBpPg;l{2rY!SE?MYr)maNoY8q=wu7`v}CzQ7>b+v z4Q^FiS|U9AXR%ro^uVv1IvlrE47{lYn#@}wOat(yEV!XV`K+F+fj2=mg5T;43W%m? zXkv28(_>&-bD=EZY$01^vjX>cqY9G?XT3o=9fvqiT=2ZBm*EgM0Ub(IGxnO zBsQFH$Vt{Ut<*EszqV^|=tyx(<(Dyy(QR|Ni>NfcSoDhhX#pqsadGlGJJ4~oyAkMq z^hM=?kT{fb6A;)@*u$^y6XH1Xw$US%F~ZEp9hxyNwGIN?gyjB~p#33zBTaQL>Zqk~ z`}!>kd)xp1$h_^GZr=dSc|kHGyKJ8UtFfA(14Z4V#qVl&D&Q42YgJak#|H=8Lprjx zwHc1S$-397clen&`WyDf>r&3@(hqe9FE9Q_;Y(NhXUZ^K&sw6eL&tmGU0@vlTw^)z z@#%?fcbu@osc?2>nN;uEtIUJGE_Q`qLa(6|{Gz`Qj*O!Nq;{jftXeDfXy!WKnjKya zPK9rSnwkubEaB){)r`0gy;dH**Hfe*8iOI9%@*&o7|A`wczCGuc7xpP?z@ftX1#Y9 z>{@Nc`j7F?64HJXepBAB!s1%P_{^j~)m48c9ZQb0F5KSjSZL>CZvM>pzzg4Jg`s}6 zdCg-hw+ojb!BAE>%t!yNKOOf%YjdB`{G`h9cwLCwT}Y?@vYSkUFU zwKW_F>Hhdj+DJun+A+UFk`M1!FcRqTqYE6%q~_qPyKc9jJg>R4*ghR!xvA){Z|}<8 z3O-m=GL~L^?bdhjY-8iQB~7|KQ7=@sba?fBUCWCHzMivBOO1(prR8wPcScjHSgOOR zx$Do_bxVtp@M1q7b)E-xAt&*x?uKIdUw=Be55Ia}E^Sh3_X&A2)OIE=S3M*=Rn_qp^V>m4n0Tk0-8D;xJN(DaW4}7GdASon$UPV zIjQls?$(|vi0ovWA|KbkOY@tVkou?9n!uSS@s$g*Y#A_d+%xUOa)CSu-pR8 zk4br##-TWr>zkvpk9M}<{_!8tH9O7d&ar+?l5_}+ibNo!^A zL2Pa<{j5v!`^DO2(kHGnStW3Z6q&-|J>2=G*srTx`s8VE=cM+8bZ?pD$u@9T2i$dJ zd%1-SmySP#;FM`Id`!%RL7yMRHN?jy%$U`+9M9DZ)j&^y?WGygTRJXm`zst`sJ|&l zo4Ek?1T{-Sg$63C**gDAvyipNZF?}Tns+HU;O?i474N%!ceQ!;7Gz_aXEThVFs3<7 zhDmglTBmsOW@(JV3ogD8nx$oKj*%R~Rv zgoZYLZxvJxUTo-Icn#L+{wG6*kr;C!eyE~RAEj}NBja={`O*qr-!9+ex+(2K{?@*O zDs(CzCc#oVYjjwap=<#_(zs^=bBjjdq1OWc{O%sFRl{u?`VJ8`t081(__kId-#Zj= zKU$?r%$l2Beox{wTFkYvjlvToku6?-WoK@+D*8SoNGtl{X|JC0BGs4U-|@l0&!O0A zPY0o<2WnIKw#!2ThWg?-!JWmUjST|j7ei(iUVgrRZM?U)tu@Pquu2E3=OZP7qa7dZ zL33OhTPp1;$jQzPtgXIhdH#gJ?$3s9-|cK#$0f)+;!z*z4q-)%&}9AA?(5ctI~-G& z&t(UtnZ3#lTt1&C;y~QaM@b%q^nV=%v}Qqji>JA{x&v&1HLo@mj(l-dXS9y$?{0mS zX)^CLmJXjv;Nqea$KV8vXE;?#rB@qopI>Zd<&)FcTfvvcD@SALL7=0}_F8Er>?jiC zy&qg45O6+eoL^$up3#*XxO=YZ+&(@^l(Sj%yGe|Y?j~vKSeGF7_K@wVjCsaWD=+Pw zT6JOcV+letxa2D`SH zWi@=Mk0q6=R~tErk-1PSw!~ODLr+}49P7${5#qIsqr3j5O@eCWgD-K zhl%u3n|`-mx#;*CPp9C4;(1Ad_w|-0n^<*!?g;NYwz|ICce$z05evIF&ocHu^-M-7 zMA=`Lw<~!3m$YMD&x5QU!A|TQO7rr)Gt}=btysb6EPpp*wRz8*qTI#;4J}vcjhdd2 zqy08w!~lGOOP6Ky_+Pu{1$}NBijNx&HMzGwCwZuIQ?25R#YurPjX2MI5^u*Gsi~87 z2JCy35UAalY>mDQ=jI(k4(C|%#(MuwJO2H7(3reDybt!Y*jwK&TI@UL<9e{gGiAVL z#g5r&YnH?~-Pq%^;MKQEj75CLkZjRz3vwT8YjtWIk%qRHE8>T6m!32pU19d|yK|{( z)!^0Efa3>++u`4`?e;fXY@`-+suwJx@N5HK(cm>mJ6>4|T0M9Do|BZlDPi?wjqylq zj%urkooj7pe~Wy$|EYXur?0tXO2@?oJiN%q<=*F)4;J-DNz)#+7gv-?y@DDWPJD7q zUSyVL(cR|b8k{@yM{?D5jhgA5LjkLg>tBw!f7^2on^vAKapjA86X&s-M_U%m3+?S0 zlG`fQ=FF%Xax?ko=8DG)d!pav;o|P=m#d0GZtzjO?1;H# z(|a42jCHm;H3dtb#>XX3 z;QoW#=kkor*tB{PLeY%8A}Bvn{8hG~DELixXwaDKc|lHr-`l#YlRo{ep3;8*UCNpz zJ&!C#zrR|NsS&u}&h^rT=|>cEmH}T!*oC<#XR}VXdIlaGs!pi9k-FTtx4J33?{UW; z`q0Cmb7+02!S=b^)1K`=w?LIuGW+|w870VL*`F^S8(jMoTa@QHvrlH!@Z0aRx-+Z2 z6O(r>FkL^sR`E;RKS4@C|4cFzKe?Xh(($7YgZx232%Z~;u>rQ=Ww0-4aR(I?o z_JMQp*auCB(Fe9o`CYkf_L@rXL>uYa!naA6LQI#J`Nkk?DzgiMhItPIhyU?8(tdJB zh`~+RQQ?};rLe8b@5ri6jJ25wp*Nn77(cnAp*K~)QI8395J;0w`waG%6$E|eEh(Pd z1%ZXSNIFJmw`IyNo)KwnKUy?CuuZgR?vNYCY`vFfSGapeYM_&QSL@c@v*^?c*b63g z8uK}ehQ_)eMUq*Jd5>jsleP#;ZVTay6@qAorASW zefrx&?PsS2@3dPPm_K_FoeJNzoo_8>do@C$6Ui|*@AeIOa?Jk|Z+5fa9=j!ln*$R0 zV(vGH!jrdWB#tefU%pg7g;?pC-pF&ReDEgo)5)#1@>k#XZCgf<#IoROr?+hm{jQHN zGcneo(06T`edU9#F8)0SGCx(sz-7jNc*O}7ma{?LS7c`SEY`bHX_M3@yJ5wpz{QW2 z#Z(n9yLRv1?!%FB(ExVV^_a-6EmD$e!?D?2)A2pmr~Q4dPe9M>M3;nT{#M2EED0L+ z`RFyptny{_yVc=+musQ5&S$rk#Q@dw%PIK>5gK;$=zYbk3SIi${lc!4!uj1Pp@-i- zklhb@*KyrO=m)!7-PdSk=PQTVUUhQK%Z2kVn-6|AF%RA28(7t4xki{jgHGM}^`^3O z_C|a}H7`HDxOV&ZYbNI7pH1GbfV}^MmkwW;PoY!G`u=Mu<^2 z7>rq)c4=kVHX$S`VONiRQ_OmQ6-|nZgJ}2!jG2N*?oJuT?E_AW8Bxk_wR!1oJqS|4 zFW2EDuU}%H@o(s_2OOmhQ-i9FW=APMgm&8=Dw3Hvz-}8+4jpq39cgkZ+8;3XI%56v z^|g`8!=Pc-LqoL826KwXZ_DJLgOulC3_g>WuD3GS9YGF0I{Hsd#O_d8u9dCNAlRf1 zNq3KbvN|?gb|APnzGw-pK6ND(5u}Wqg8nA+id}_RbUdaPUPwizUJm**bhvSyaR___ zP@_{L+N+Qf7mcR=)FanTLW;?EpL&pzJBuH6J|2HGD~1ENXlrqa$Ai^~-_@zV2Y)@1 zEbC!JEA!|qL)#t|j;><^(c^|VOtwmsO`H5=yMibtrMSE5_ZzR? zhx8g>feX-6sPpXY`o49nW1o*jQO1{lMYGs6;&&U?V(cs$hX3jUN=0HF9{v*#t~y&R z;iK>^5-GPK+MS_&a}>r?VPQ~aVXma}Y@t6CK?-<8dlUQyWs5csT_fhgXHO(o1&6{* zM(~Lg@AYyjpf2E}P~Yi*PvhyvgaQ0(>PvkB%N%TVq@XMvI`uNZ_LH!$0rofvn**>= zMZ#fC0k(;RodU2ZfdyZA5p*>{<`$@4iNwuHVt}j`Vc;&HLT6xD@*3KICHm*%Ki=^s z`tOA+3YJO`z<=j6Eu0YdK-{LCBt`sfG$BGw5}6iDiul{Jgt!1INz={~q7)aC3DF*0 znCwLGIstaAG28|G$4XoyA{_8l9nm9U6`{S1P7DH+X%W3d0sx#nM3CJ8^#f-U+!=8+ zfJQICox#h)T=?VyfrSD9l0|Uk?F6Ka1X31U7}Mbs3k>Huh`@$5IFl=|Ig5M=P&FLX il!y@WfBZMxJ5Fhu`EUSvIOhv)YK`?;{%xK|`2PcsaC$QU literal 10330 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.memory.png b/third_party/test/golden_widget/flutter_logo.memory.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..fc9ffa27529c1c7d62c7faecff5822448e6a262e 100644 GIT binary patch literal 10130 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 literal 10330 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.network.png b/third_party/test/golden_widget/flutter_logo.network.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..fc9ffa27529c1c7d62c7faecff5822448e6a262e 100644 GIT binary patch literal 10130 zcmcI~i$7HB_y3+TW$R`SLZ#+HqLU(&#F(aGCf@iXCgCbEXVYQxc# z?#6!;ymklI%i8<9tZfV5T8mmxy2i#>_e_;jI*$&YplVQWY&-Xtec{4M^-8+uHtc9q zw*AgoJO9cb4NU#O670AA519u1K%NLWyXkjs5>=;rs-g3?Of=)~o`4+{{SHT*1|8f} z{j0uMylB_XHL0z==fBJT^S$Qa{rVJO^?&&%e%&8TL0;Zi9@4hEIR05@^FZ)i!;Ce> zgCz%={9KzaQ1)R=WP`mBJ1bB3qtZkRqm+3nj1627;yhQj%C;rK4#kk0Y!13c=uD?j zxu&IxtSIG$+FT?nT+Y;ytvW$Nkup_=Scj99h)~kKTOuT-iZfN2h#Coc2te5cD3gom z#o>J@`tt$lR|3fle|wU6YYa%%7>@J-rBF*g5S{WR2*u+iq3UKQLJZvqd@XwrfgG4h zu?5kL5O488)FVX)5H(5B8bp*79YqM1N*J3%XCh)<+^v#lVE0$j*i7I>!tTXYV+qyG z5CI+?=f#`@?Ifz#d@h2n!ow!&g8q+*2&B&hXLk@#FK2`50fM*pIf#n}L7-r*2zj{z zkE?THzJBv`VQV0*rRG7$2GA;m`?m{9tiI5Gp1kyqj z6a7UZO{Y+u>4aN1Ap#4@xE`jV+(`tJECAIbLF)i?5((-Hpw0y71^`tfKoMM%oDE$N zph<+&B7M-r2u(u)XmWA$h&rq%g$4KsBKE+9LV$`qK@1~;B2vZQlHyGKEr~T#3Eq;T zDgKsN2O?AaEh$ciw;u@F9;>M|rXk^0eKD$r=J# z1p*a?mA)6|1q3-9oY_kDFQK6&CkZZ0GYU1IB%q0as7v(HguNtxGAUvpvPn@BL@FsV zDOA4+Q4hpv7YppF5vqET2&JAJ@e{zCn7POl9j@pz z8LcZc)Y+8OyogY4&L`%^2~{Td92r6?m6k=$tqpL3Y$PW^G>WCqCc@%8i$dK%>@>(i z0Bs>buK}nD0h$G%(In_O0F5U=!T&@75h`1KB`lqs4J8x`RgG9~$VC=c#3md;1Ssb5 zmFOgbz1+~7Fk0e5rD-lA@ISbL2pc`@Ss(ZyY7wHxd=N?hJ$8afM$N+jL>j5Ek4i(G z2nzKOARe&}kY&1DQ9fxb7sc@N17JP&fGWwh93pUq_bOFp36C7c4@%evl;n+4X%|UeYO6(vBB^>6cwf`uz#f9A!5-EUaj{g98&5+w zkRIxtN5Y~>d}~#vvp$J*luBC&ePD;%uu8<;Nh0~8SXLzAmNT59=g7F;)aIsBNw?3@ zP&E=X3qZq3(2W49M}i)w(x#B0aDb?hv%w<`G)bo&=uBtQ5zz|JBxggu2nh=#Czcye zR3ailwN{HtxTKiE6_p^Qcnic566=;N=uU{MKzBl11G=QRmn-7>5wwvxDol(VtrB$_ zN+Z`ILf-F^KVj?0e+^ICQ-+`Do>9BZ?lg_?m zQ>d22l1IFgkg$0qfdC*NB>~LY-1OBXm$@p;m*jCKidDioCSa9mXu$;R0xE6G1gtiN zYCytv0IWI*O9QgTBv~d6^&(ZVNF>aGv=vTgO2SC8Tq^B<6YYsen88GUU9QIjmnTYC zJxQPhK{2-kqE`tQ#0XLpff!GUB_I;8@nx4d!{3+O*z;!0vH1<9_L<|ucjL{8pEopX zAk{=XH$Upkcro7F)6=7voLDs&Y+z_DbT-julDo3@=?J-IT$y70`_YmEjbFbE7opw> zNZ5RwecYl_#Z^(tH zxmiT!OWLMPMX{U2ye5s6s8Ge^X1_U7Ib4O|H;uxp{!e$aFyso64GYv;BGOA0VS+mo z`{{)BO(vg5s0bk5#TYPeJ*L}m_0F%uo?;9VFJBk%_$Xwq6VDV1PX^EQAI~fbZzdnT z{Ih)$g=Y%SKilVnJA4#URIso=@imPQ+3H5|9n{Vo8h~&qN`& ztDvD9Ratu-g`~Uq@~DGnhab=OFckEslS?PuD}Y7Ip+EiW=d**TM2-G5>c=xInG!Af zQ2jH>^rg%n-h`_%CGqGiCHDsfy9%bqa z3p8qbdRCSxK8aM;gP^2FN*sPP9H~kfx+gpOJyvFBSwHx#gd?L&S~_X!@m=Px)j>y5 z7GLx40AslGXbR`GN$0o6J2daBGMpiYqeM!kgJtznsTjTD)S@s2qKDG&PL{=&8Oe-T zyp9OD=&2Hh^2N8fLa#eKp+hA0P=}KanOHcTC507oi_TDGix)>KXMrOkemS*8`}Fh{ zPoDUtu8cC1&cqVYBsS-6J)5J;NB3b2JV^_SlIU=jKF9E$DW!@VY~c{uD1eZ&J#hnv zKue!ORdC)Z25ws-<6t%}12ve(+zm5XU_iYU4CE`xD3He)GB@&}>(vPPMT~W8wGg4w zPG0XoVg3YY;s!QGD#O9e^^ioL!DR8)%D7u*v2p~mbj_@*Y`)N|ny{))XOzH2P+=1v zw@Sq$@@ujjiN%4Ztl-R>Ql_fUZ$U81)2Bt_;EbN^}&$y^-mh<&0a<^n;K{ zmPRS#8RHanHV?*g5>8J4v>bV@%T4!tY=gT`klTqdN^Bq}Nxy*muZENJsxMW{hYQEK z4iloQ6uQoWq1kIK;#!+W;eJiR37@nU!gZJFoU}MB2XJB;ThwsFveC@RyT0JK|}Lj&9Ume*KDglUv|e* z79WE?$5ru5l`5klN@7u}`117Sq9sVWS4+msH>Qrm*JNhFw|#01g54`1HA-I&x3>8$ z85`MN{w)f4A;CLL-XTUer^%7y3%HQ9FfOaGa#R^yNE(^ivg)byLrY~8F_bKp(ix9c zSbs+;<9RM53+O7b)_jf#?*Ap{O9guDHi;bJk+(Az33=1>?5UuIyS6TBpPg;l{2rY!SE?MYr)maNoY8q=wu7`v}CzQ7>b+v z4Q^FiS|U9AXR%ro^uVv1IvlrE47{lYn#@}wOat(yEV!XV`K+F+fj2=mg5T;43W%m? zXkv28(_>&-bD=EZY$01^vjX>cqY9G?XT3o=9fvqiT=2ZBm*EgM0Ub(IGxnO zBsQFH$Vt{Ut<*EszqV^|=tyx(<(Dyy(QR|Ni>NfcSoDhhX#pqsadGlGJJ4~oyAkMq z^hM=?kT{fb6A;)@*u$^y6XH1Xw$US%F~ZEp9hxyNwGIN?gyjB~p#33zBTaQL>Zqk~ z`}!>kd)xp1$h_^GZr=dSc|kHGyKJ8UtFfA(14Z4V#qVl&D&Q42YgJak#|H=8Lprjx zwHc1S$-397clen&`WyDf>r&3@(hqe9FE9Q_;Y(NhXUZ^K&sw6eL&tmGU0@vlTw^)z z@#%?fcbu@osc?2>nN;uEtIUJGE_Q`qLa(6|{Gz`Qj*O!Nq;{jftXeDfXy!WKnjKya zPK9rSnwkubEaB){)r`0gy;dH**Hfe*8iOI9%@*&o7|A`wczCGuc7xpP?z@ftX1#Y9 z>{@Nc`j7F?64HJXepBAB!s1%P_{^j~)m48c9ZQb0F5KSjSZL>CZvM>pzzg4Jg`s}6 zdCg-hw+ojb!BAE>%t!yNKOOf%YjdB`{G`h9cwLCwT}Y?@vYSkUFU zwKW_F>Hhdj+DJun+A+UFk`M1!FcRqTqYE6%q~_qPyKc9jJg>R4*ghR!xvA){Z|}<8 z3O-m=GL~L^?bdhjY-8iQB~7|KQ7=@sba?fBUCWCHzMivBOO1(prR8wPcScjHSgOOR zx$Do_bxVtp@M1q7b)E-xAt&*x?uKIdUw=Be55Ia}E^Sh3_X&A2)OIE=S3M*=Rn_qp^V>m4n0Tk0-8D;xJN(DaW4}7GdASon$UPV zIjQls?$(|vi0ovWA|KbkOY@tVkou?9n!uSS@s$g*Y#A_d+%xUOa)CSu-pR8 zk4br##-TWr>zkvpk9M}<{_!8tH9O7d&ar+?l5_}+ibNo!^A zL2Pa<{j5v!`^DO2(kHGnStW3Z6q&-|J>2=G*srTx`s8VE=cM+8bZ?pD$u@9T2i$dJ zd%1-SmySP#;FM`Id`!%RL7yMRHN?jy%$U`+9M9DZ)j&^y?WGygTRJXm`zst`sJ|&l zo4Ek?1T{-Sg$63C**gDAvyipNZF?}Tns+HU;O?i474N%!ceQ!;7Gz_aXEThVFs3<7 zhDmglTBmsOW@(JV3ogD8nx$oKj*%R~Rv zgoZYLZxvJxUTo-Icn#L+{wG6*kr;C!eyE~RAEj}NBja={`O*qr-!9+ex+(2K{?@*O zDs(CzCc#oVYjjwap=<#_(zs^=bBjjdq1OWc{O%sFRl{u?`VJ8`t081(__kId-#Zj= zKU$?r%$l2Beox{wTFkYvjlvToku6?-WoK@+D*8SoNGtl{X|JC0BGs4U-|@l0&!O0A zPY0o<2WnIKw#!2ThWg?-!JWmUjST|j7ei(iUVgrRZM?U)tu@Pquu2E3=OZP7qa7dZ zL33OhTPp1;$jQzPtgXIhdH#gJ?$3s9-|cK#$0f)+;!z*z4q-)%&}9AA?(5ctI~-G& z&t(UtnZ3#lTt1&C;y~QaM@b%q^nV=%v}Qqji>JA{x&v&1HLo@mj(l-dXS9y$?{0mS zX)^CLmJXjv;Nqea$KV8vXE;?#rB@qopI>Zd<&)FcTfvvcD@SALL7=0}_F8Er>?jiC zy&qg45O6+eoL^$up3#*XxO=YZ+&(@^l(Sj%yGe|Y?j~vKSeGF7_K@wVjCsaWD=+Pw zT6JOcV+letxa2D`SH zWi@=Mk0q6=R~tErk-1PSw!~ODLr+}49P7${5#qIsqr3j5O@eCWgD-K zhl%u3n|`-mx#;*CPp9C4;(1Ad_w|-0n^<*!?g;NYwz|ICce$z05evIF&ocHu^-M-7 zMA=`Lw<~!3m$YMD&x5QU!A|TQO7rr)Gt}=btysb6EPpp*wRz8*qTI#;4J}vcjhdd2 zqy08w!~lGOOP6Ky_+Pu{1$}NBijNx&HMzGwCwZuIQ?25R#YurPjX2MI5^u*Gsi~87 z2JCy35UAalY>mDQ=jI(k4(C|%#(MuwJO2H7(3reDybt!Y*jwK&TI@UL<9e{gGiAVL z#g5r&YnH?~-Pq%^;MKQEj75CLkZjRz3vwT8YjtWIk%qRHE8>T6m!32pU19d|yK|{( z)!^0Efa3>++u`4`?e;fXY@`-+suwJx@N5HK(cm>mJ6>4|T0M9Do|BZlDPi?wjqylq zj%urkooj7pe~Wy$|EYXur?0tXO2@?oJiN%q<=*F)4;J-DNz)#+7gv-?y@DDWPJD7q zUSyVL(cR|b8k{@yM{?D5jhgA5LjkLg>tBw!f7^2on^vAKapjA86X&s-M_U%m3+?S0 zlG`fQ=FF%Xax?ko=8DG)d!pav;o|P=m#d0GZtzjO?1;H# z(|a42jCHm;H3dtb#>XX3 z;QoW#=kkor*tB{PLeY%8A}Bvn{8hG~DELixXwaDKc|lHr-`l#YlRo{ep3;8*UCNpz zJ&!C#zrR|NsS&u}&h^rT=|>cEmH}T!*oC<#XR}VXdIlaGs!pi9k-FTtx4J33?{UW; z`q0Cmb7+02!S=b^)1K`=w?LIuGW+|w870VL*`F^S8(jMoTa@QHvrlH!@Z0aRx-+Z2 z6O(r>FkL^sR`E;RKS4@C|4cFzKe?Xh(($7YgZx232%Z~;u>rQ=Ww0-4aR(I?o z_JMQp*auCB(Fe9o`CYkf_L@rXL>uYa!naA6LQI#J`Nkk?DzgiMhItPIhyU?8(tdJB zh`~+RQQ?};rLe8b@5ri6jJ25wp*Nn77(cnAp*K~)QI8395J;0w`waG%6$E|eEh(Pd z1%ZXSNIFJmw`IyNo)KwnKUy?CuuZgR?vNYCY`vFfSGapeYM_&QSL@c@v*^?c*b63g z8uK}ehQ_)eMUq*Jd5>jsleP#;ZVTay6@qAorASW zefrx&?PsS2@3dPPm_K_FoeJNzoo_8>do@C$6Ui|*@AeIOa?Jk|Z+5fa9=j!ln*$R0 zV(vGH!jrdWB#tefU%pg7g;?pC-pF&ReDEgo)5)#1@>k#XZCgf<#IoROr?+hm{jQHN zGcneo(06T`edU9#F8)0SGCx(sz-7jNc*O}7ma{?LS7c`SEY`bHX_M3@yJ5wpz{QW2 z#Z(n9yLRv1?!%FB(ExVV^_a-6EmD$e!?D?2)A2pmr~Q4dPe9M>M3;nT{#M2EED0L+ z`RFyptny{_yVc=+musQ5&S$rk#Q@dw%PIK>5gK;$=zYbk3SIi${lc!4!uj1Pp@-i- zklhb@*KyrO=m)!7-PdSk=PQTVUUhQK%Z2kVn-6|AF%RA28(7t4xki{jgHGM}^`^3O z_C|a}H7`HDxOV&ZYbNI7pH1GbfV}^MmkwW;PoY!G`u=Mu<^2 z7>rq)c4=kVHX$S`VONiRQ_OmQ6-|nZgJ}2!jG2N*?oJuT?E_AW8Bxk_wR!1oJqS|4 zFW2EDuU}%H@o(s_2OOmhQ-i9FW=APMgm&8=Dw3Hvz-}8+4jpq39cgkZ+8;3XI%56v z^|g`8!=Pc-LqoL826KwXZ_DJLgOulC3_g>WuD3GS9YGF0I{Hsd#O_d8u9dCNAlRf1 zNq3KbvN|?gb|APnzGw-pK6ND(5u}Wqg8nA+id}_RbUdaPUPwizUJm**bhvSyaR___ zP@_{L+N+Qf7mcR=)FanTLW;?EpL&pzJBuH6J|2HGD~1ENXlrqa$Ai^~-_@zV2Y)@1 zEbC!JEA!|qL)#t|j;><^(c^|VOtwmsO`H5=yMibtrMSE5_ZzR? zhx8g>feX-6sPpXY`o49nW1o*jQO1{lMYGs6;&&U?V(cs$hX3jUN=0HF9{v*#t~y&R z;iK>^5-GPK+MS_&a}>r?VPQ~aVXma}Y@t6CK?-<8dlUQyWs5csT_fhgXHO(o1&6{* zM(~Lg@AYyjpf2E}P~Yi*PvhyvgaQ0(>PvkB%N%TVq@XMvI`uNZ_LH!$0rofvn**>= zMZ#fC0k(;RodU2ZfdyZA5p*>{<`$@4iNwuHVt}j`Vc;&HLT6xD@*3KICHm*%Ki=^s z`tOA+3YJO`z<=j6Eu0YdK-{LCBt`sfG$BGw5}6iDiul{Jgt!1INz={~q7)aC3DF*0 znCwLGIstaAG28|G$4XoyA{_8l9nm9U6`{S1P7DH+X%W3d0sx#nM3CJ8^#f-U+!=8+ zfJQICox#h)T=?VyfrSD9l0|Uk?F6Ka1X31U7}Mbs3k>Huh`@$5IFl=|Ig5M=P&FLX il!y@WfBZMxJ5Fhu`EUSvIOhv)YK`?;{%xK|`2PcsaC$QU literal 10330 zcmcIq`#)6O_dhcxj#AE`C@~k8=qgHb8DpMtDY-nP>r?4Tl2ppA7#W$0iczWDLP+X1fi}&WkHh|c-R;IQT$wNc}Q;M>~?sd`SDh)M&VC@dPE`!6IsExT74k7 zv)(>-`(S9bWPEvj`pk-xmrw0pe=CD_Y?7|-x`v0dm7ZTNJ3d|g+`f!|bQfysn>m}i zm^gFw%a8>8Va`{i+W& zr_9dDUK^Sok02DL3PJG}-cF!$*HCFfj0m9&Labg+v~PfHwZ-Atpj-!2e;Xp2HIP_S z((5~*s*{1)K)A*$34>^`^*Kqnsq1i&4=4dHUkF}m^C?tkl7TFss*p*1qRd1lDd8cc zp;TI$0Wr2JKvsoMgm?+XggjzEoo9nTLQpxb%|&D#iT1zcF(HLWL7Eqp=AK4$rI&(G z)R=^+9VmSX<>yFHl3~ZQ!JmiwBQ1bWA(n^G2*eZuO6UioCMizAwFE(-J+39iNw}7d z(-uww2AZU(gKJ4J9b8L_(?R>0px|yzr7_7AtcyS>D3Jo>9YjMVVHF@-WC~)Vpq)qo zVh96nMWlf13I1dXyuuMmTRbth?(l_(za0_H27odpmJ+f6601QHmq%w_$I+JTj4XUGxJrRN|EOBdcz^EveWWh53)X15;5YD$KCXQdFiKzePM!xcu8(HO&UsS_^{D7Og3m?)#j2R#baM?`?- z?W5AXE|9n|W$uu;ZD6~B#PtW<>m;rz;Qk;3!)RzMS)H+?2;~-;4j!G!ok0vJ*Mv%2 zmqegq@aB6*PJa<3@hnmAkc%*OI;80VFij*0OaYP1LA5%F#Yqu0D36hfe=9MN z2yJefFTtzWT^`dT85lryoJ=NBAq5Gik|9`QOlLJ>d8Da9I~k&iwUEmq@taUgPe@R4 z)}~Nph*uz@VlONfPWUS`4V=joNNA`684Fj5X+W+C#1@of*u^T~PrNb^16yG+LM#s? z*-FT*BB7H15OT$&_!n2mb(#=)Larhy&IfH3={DaEY$rrOaGDTTfGsIr16wi$$UG$` zMy8;677c~v4ci1HPnSZakgy(1E|W}wa22$ZDTqCVgfod0Aco3Jj7$M{3JvvNMXca7 z9V*R~*l{4$YzkF_oI73#Ncc38fR7LfpGr>O4;Y22PTJ;KQEA3xQFnhvLwzQ2Oq=fkx2L|lI>wSGd7$UFfNx$dpFS@ zhlDSk@Ym(KTN49@JdwxNO_(a8*gAM|!~Tcs1ma;*6oWW1qE#RgWKUIW87=(9SmDrH znOjOxmdiT0ZRF>ZMZ>)n*zO<;B$9Y3m$i&;c{F(Q%FeOi_sv4(3ibYX19GE7o>$9- z#glNJVxNZb=OGMx{U}B1&W5Y^?paD3$6D^LeW)pa$68ptoU|#ClSC^1!{mNezzN$L zH$@yMk^6=*$tqq3Wk4)Vn@^=(AwsK*RBWO%;$Uvk@%(71ORUVBA`Im**v6*)=dHw4 zA!_i1w+~fxiI@hYHkg5Gh&P4yy=ZlWNV&FdgHyy7tNVpbTbOdGx zksq%lBwU{@vj6@30V<#$A8l3oO;?{vt7P(^K29VIPqWY1)pL5~)Fsd*7{fyGk`71;U|M~0D&}&=~ z)VzuC?BLl>1m$kx*$bYnL<;};N5b<8QQv?5S7H4!dBJuQ^tm2XnjxKK!Tz0XQwnuv zR4nWv$#G?H7tOd`?EREmkt6mGW zh%55v{_a0j9{YgNZ(04GKEsZ}V%ezJslN#r(7<7p2zG=M`F2LJHX*t*{CB{ttO89W zt}Vy1_w9Ex#ja32x3kM?X2a~T910m6w^>=?&tl;*qr#ci}O%M33tgYy>v92qT zQ#gx+BmA<-&_QPNHlC<@x`gtFE|-bYZ_y;DDuyJBS-cNRKsSfWgt!pUeIs-#5{eGS z#7?65FgBhNX*|Zd;~?PbL-p6@RWdoZ)^j+zd~`RR;S9%3tEgCg;8BZr5t}3xzCkf` zl}KB1>h&;=R%R{WMuF#Ae-UK5=Xt3J-MXnsW~B}{P44(fOmfO$4DaCDN&)vJ4ejIq zNr$j^F2Xx_rNnTCLAG$=&!vN;-+QFPRDg!O~B2-Nr2pj9zHPHP#$VR1*;-4-4Z$9L?k@rdjQ@;Qwg|Q36LG| z(nbmiZjW$o-;@}|L-3;J-@rYUmjO4sgWw4pPMJ3+P+0CII5(GR63SmNCyGTecvxY0 zrwXZ3WQG>kUC6V6d4DAg&&W}G0dfN07hEKWG~!*rc2@We#nkdJJpA@BAQ$@uV-)v5 zw|`~gx|xo+ZcLd`>`g;e($3)BD&T3d3yV^84}i_d&DVsEpf?_==xzbJTc-$}C1D4; zP|($Q($?TqTsPxgJSdTi6(ixi?a_D?`8Z>EZ*Vt*=Q$l7Udte^ z5*9}|0zCFy$MGY@2iccHnq<6=A(S;Iz%5#8B1YR|q{v4tt}yP+X*>Wr<2;>}G>0P$ zl*c}Q;E}2mN~|OZeE@cfFOHC^S4yl-h!U<%KF1kp5tV$64(}saRnVEm37$ApEzUa~ zUJq^sSbvfAy)bYz-Au7N%tdg`N${1;>!CA>Ti}oh>oY$pwm(WSO?~4gMZ~?W#CF~x zlZ@eA`b$6QyNUfR;>RGoAUNEdD6!4qm%$}L^#TgDT1j$~&i2rUQx+VSy~3p*^ys%R z38e&%_J+!g3m8jPiNT!>Cpaz1Ykm5DU1)-{qamHaij1AvBohfY2OdlgkIvH9kx=+L zTsX#ZcyrBpC34t#gt9I|ie9gVj(d7Z&@)KILIq`JDXBCyEmm>YFpn-RF6uPojX8e_wj@#wQV`=M}A}0Bm z;NSufVwZ!LvnHGwtpu@u zUcv3)&dlIIQ^bsGu+U}nAc?XLg6d1tae~{GnfT3|vHMFfM2Lgp6WIl7V8_&fV_~c` zP3Alw7{+7F;d2KtVxK*!lpa}~u@@@1*R(*} z8)L1i-JD0GAGds(Io>!v_OH`uWzs`UWv(`KDLQZY^Q#7(_g+_W)33El@p7EYZOcQg z&m@C<6h8(i97QkMACpMTf`axm4u!Xu=6DWXFe_+OW#Q)q13k8AVRA`neVz1b$Lfr^ zZWUu@L5f`hHxXhoX^Pra)y)q>a~=70t9|{++bv^t zZC3U@7q{B1EJaJF{(+#})$O6U4`v@Ni%cB|lRR(5t= z$FnL|w~VW{B-NE>k@Ac}SM%QFk^AGBOHt1;h5mC-uCAiLw`vf0l|zi>|JYK&xb zs&Cx#u>Yz3edAFh#2>EdtTEPCUo}S2@>z`*^Elb*WhUlB9X}TY8ul*MV7Ph5aNfD~ zYHfT!z=wGU6YLLBUQCO-AW*O>=A(nFk>;6%SpVU*M!kzO=4y<5>)a(5HlHVSfr|{t zyxWpr&98Hc#_QfYEh@;4Ik(B7d+6$w0YUkqg2ZTXbE}hFcdj)`+;!NB@=iXJN~7PG z26b`FdXMB=FxsD5Flvk#epO+H$~|2xMaU$K$vwqKPng7r3wAs&on+goS!%m-$ASXW zLu2`2xh`5fAzT1*Z}L&qq3prO7&GgycvTct* z-=Z-RbBD8B@oc)wInS^ieI4B?bcRvpCWi$@*;k%6m)py>rdWQm%V|x@>1RY?Y29Eu zlW#XOarDCLc}2h4mjza?3k=v_WxMq54{s&L?#`hH9*?pPict#e;E?1$L<$>k7a0YA zYYgjYkak^w@iCJ8S+$@b(W0}XZJ9&pp}vuX=H{;lts_2bsFmU8$$9vx zci&7pwGTcKtP4lmkHIuvo7tS6eP!WH^E%(nZZP4l>ESyAAqTEb=P9vnc6M9L4js%0 zI~ZoJ%Gi+-xYV+DUq@uUlrU<85t+reTXjYnpE`6^_q;;og+Mn4PqP^DM~5siVNwPr ziF~{Hzd{sk8%LLoHy|OxPNiQ(b6CLbGG7JQpzRB3YRZiAc%2t>_>0W&!0cGuXQ~?2G32>*dn-j=x)EKD+2p>vf|o@yqMHz3XbVbv+l(T($F1cWH@p z^R`PXDnh1#6Wk0}8`4j|AM1*Eecy82NwX`)vw7Rtot$S_LW3_S@9V4@Z9dj~yQx`vCnxI{$J01DbBS5=>+ulI3?pR?Bfy>n`wkY{ z!{S$gqD|xQzm~x!n)NB00^Qd7y~@2Za40$d%gCcLwKaldRgKIdClQha`ygXG(KXMo z!6$7Si-r`Pp4$fa-!JuO*`_pWP6)?ySu(sSqfds^Bxcpcd^?niQjB3EHy>A#&ls6MTlE|<<7Q_2?FFy4Si*O}*03y0pD@I*a=Y@@~s7dp;1 z?%%l$sA10z)?8k5srhY@t%&?!pv2no=~JQQaLbL+k;<;Njp+k*fcNv+sUOqv`)Q|5!$?Vyx~BQ|E~ow zO;Xyg#&ivsaQf$FB%Hai5c{^M|5)~&)O&CC^xDl@wzg*TZ4Dp696lPG1OS)cP5>B% z1w9H0GUl{66_`H$BJjSqZMeJhwNt^zz4zWc$WIJR+_m#Y{^@DKJ;o4l^04F|Ip^3n zY>&Nyu)h8+LuSpA`uC1ig7Sa+7Z;9rcYV)1x23}T&+nGctOsfWKRUdBj|pOWJ;^Rtm~f0?(fN;QP3)=qKZH=aSsq z%wz46C64cF4m~uCY>S`669&LQ6(60&3TX~WzcJcV)fKa)XtX6^QF(=+eEt(tPJc(= zt(=-y*Nl5r$0NMWqHCi2(jK1GTqDjb^k2Gk(xbb_F?Wq;VP|P=`4_Fr8l(+vyHcea z3kuTTdp4zKdv^DkBn-tLk4c!?dYjS8*lX{)JEOkCCfK=1-{RVyjKYo$^w*1Ff#l5X zp01pB?5Gk!#B!+QSYWB2WU<++#Y2MOtM$)~lkeaCnw53$&E`-oi))R^ns4{6D5#Bo z+vjg|(2-4Bcf_D29+C(hWDdP#kE>T$6VtTDM#su5!d_G&wC zJWkNuQ@GUPL$GP|_tF}x0G-~V^l?~7@HMhpD>OQ`SsK43@NDJAz`H-nZ8aU-G7E=o zKGq$YTVK@UGiz_XlExH_Rcr_|wW@CcukwW02;T*?G~Wr>!Rfejzkl7w{2u?{pJj?y zBm*1Y92#v)tXi*0r_T32&?-Y!X*zO#Ph<8CPS1YtH@%z0-^^Pp1#dTI<$ho7wo$(} zAp86ExNK9m{x#XzXG#?rN6)c;y3=lYpK zMyXiiNZBgU>Qc&^)&2Xt%H`}nK0Y-qmveSnuDQM`mCh(8JRU3fnuyA65gPKf7bESb)66Lz$%%!_Xgl&UPeO#%F(b%4~VPW4~eolaI#1$8d$e z)akc^1()OAytH7J8fh*|ap;e}pV2XFq+h$%rMYwGPq2G6&zwuyZ&UVAvQLc}@Gl~i+`K<@da^zh`0%l{*h5(+lsEKGx}>c?))CbSh>+@WGJq~*75mKsh$`O z?>Uemr&nf5zvV4>`#$DUbIa|lhx>c=4ChLoET&VpOS~1GC7h0V%UnWx>+Xz}n7M@Zzif8BULprq9?r5i zhLIy1w0R3ph&%r2ztjKWQ_Z{PZoB@wa}>oj77siB668&$Q=he-Wu&>QT9+M^{JDG6 zijB(}&fVMd*rHZ!VHT2*CWUV4PH(S$nzy$0sl*^WEMbp0e& zHf-9_S7r!eL^sr6^!I1FhBhZaPP(Km`z24VL}F^X-BkF7I!)`V``}pE(C~?(zSh8? z?EAIvQ#p^B&VuUc&_(kFM7T{{H0Zk5^h3kw%9_iJ6mwlpTOu01Rk8;uKG_aOZa$0W zZt_SA@%^W{d-QG6wA>$I`Pm&oQHqx^mVrXUbi|~FXn1pX_*GVRgAON>C*qFR!iifL zZ!_MkbtB`LTv$eK$6oO8atW?_Qadc(Q~2}Eby&97UKGe6s=-aRmcKmuz4|lavKi3f zR$bcgD+Lr$efaCFV&fjoC6;U4YEzFZUNTUoj>0bE!Q1*90_nh$(NTuI!*F9$gdQKo zFGk#1K}9`ZK2?m?Go0K;9VAvNY}#;X!6d{!A3s7S=F~El=@*9d#7on54T!j5@f3=? zK2bruGlwK|-5TxSb7DjS)~47!3%U07-IPW3AB#2=CA$Pa{(iGqlz>IzKQA$)^WY%# zH~bXfnzaZ!g@!+XU!v?%X7ROoO!&0Moxv7G^3f9b6-b#4(Y_Aa*GFM&B^CykXiPKG zAGVQqctm>_{-YQzUZkCfdml`%E8$RS@TpYzj_|6U3cqi$iNpc&4uUqCjvKhcg(rL( z#@&kHha8BpBLP+cxc($A+`J*CByIuNULbMd>QGoo;!Xp$D8cqC+)bf>5CD(B^diw2 zToqE7vkA6vkqEysBKjJJ_N|0}9@Idt7vX;mPFq+C%3{;0Iq<83zQct03UbtUloWC8 zaYBUqQKT=16mjioLOhRa;R^~NsN!NGA-3Woi3>Nkhysb534zIyY}Z3HRzyBN!_P3> zefcOo3WFSeM{5TKrE16vQ0UFNlX*Do`?>vBy{6GJ3cZ^x`Zf0Ara#Wjw OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png b/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png index 6b12ded3f96226de0bef22a1502715fdd3b1c757..d46b6ded9b7b4cbe558dcf475ae18bbc7c50b096 100644 GIT binary patch literal 9032 zcmcIqi(idd_kYfD=t12yyexi{nxCN!?O)hSPPhLhXLl*FMT zgj|Ypi-ahQnQjy_g-W_9N2QzUx1PP5_xJt-Z=X+m+Iy|<{;svxUVE>-pJ*R%*Ac@E zh7klY!rjfummmfS34*(r90D!Jw?}S*|2SKHU8Tg8KgZX@AH1zn_xU9J$jMbof)En! zP7d>Tp7>O;Z2z*dUAdZVF0JCVHFwT<34Q+g-Apw0R7~T$X))7^b>>?r{4>X%^%-`y zP#Rh^YTq~U&+)F)Zd5tRlv|E9<{2%Se^38YQR4R>doSJVxc;iUS2i;-<#1-$`>a3T z{uS;%6vqCa{m8~%zo0|x`P>@k?-iy^q+h-Nb;-eDhTdTWVR?2(=h?_^#!RUr))i#BF@%qu#=)s7YT;0dxM(I(y2%S?aJY090`&vX z^9Ym!I>Vw_olOp)Gn&;IR7nYm`3RFqgE1FS?3nLtKwX2>7kh%J6%vit6B46lv%@nl zLDX576_we6=w>8ZegK$SAf`dyprwtpZWz;qMI>t!=WhT|n6vzHHvqsX#3g+e04zpY zO|A?s4*)_8v$(}G(Z8{zXw6>0#l`ktI(dq&8=L|~68 zO(ZCg)+0bY;EgQUOj3l4DdMsdxTGLo%a+1ebCFvuB>?*l!6vY90ZH!C_R1us&0EKAy6+n+*&}9I+5`ks{=zIi9 zfX;77M`+67`WPa1btJ{?LzL+xf^#0b{|_)}G;%NF3`*~jl589(St6yy&I~aMW4;1M z4MuUxcmdQy1eJRZv>dS3cff=~Owy+S0D%C?VF{8bY>4eJ>s&;d2?Ky+thJoW6AF=N z0jw+@axZZk`e|%{IfqMOt~F+$kGYDVKN>kL*M~>uDln8AmnRb=0+v=Bt|bSd>O%nN zA46U{0LC0}W4%s1F`)?;^tS*Ne6OG1lf~7kHqbdO^5%*8zaMQIAEhXfJCd}nD5SWEUbpdJ$B0x_7tuaU| z*#rnUA_6`J0D$eXI81OBqvS()fMXY8fZrjSOtDrlXkpRw5d^|(H+kV07(-IYKOv;TVH~cNGjgk+ zm}b`C7+cRH3wg-YKmfgnK`#U7OANZ2%R7%jGXZn~0)@Es5h0y-k)VU;=dOrm)*(z{ z(NHRR7#cHo8<%I1h&ZJu5S)E@CMKKH%u3`wA`L{{uxJQ~9>SvIINVW~Y557z60s|c z2!h1qjNC`u0D#YkA5%e6LY%v0JGeX&e259Ihu`PWp!kjv1a5?b!?wi?#LuY7w@eniA%o#{+0cN@j(Pxy2(b zhanfqj|(?81@{%HeoD%9vO24k)ieyoNFjw5-a&adJHCO z%jK1;aepkq`HJTt&y;3PVpK>1@LK^~cUQI-}VAkz=!a|&7l1FfP2G~KFjtuRHN4h~$fjG+)!ZtGk zd+iN?Zo#10JaRq;4FpgR3`$bx@y0+yinxd|3;9AHKAIl}HlZUJD8Zag<{}_sKS^2O zNz0wV+3}qH0R$gSP|5Yba%bx2s%h9yv;i7Mtv601zUdqz~tC zA7Fqc4~CXufF4Rn#i6Op&Eb(e?7o;NB0`3YCbsZ}6h@`Jxx7fswZMy^39Ro(2`%w{ z$($mo1Z-<=43G45!UO`jJTpwd5(2;&<#s}UKM?^3GB_#`2i%!lH$2u8Gg`*Ou=4;G z?=H**lF}c5jpLEp1F-A3ydfBtiXbBXzyPNyVa#D<3=R2k1`aEw3qudVsQjT+c`WXq z&*gm`&_6~*7-B9?=Cn);i<(lxbR2<0sm zM`H>2*KT*8?a7lTy~6Y@EjZlSD4Fd-|7J>=Tof6uMu;06Q!QQ5xc@n;hWrO6TF1|X ze)j_#UB)`>zwD_Ml3YUGzuJ02t2zIry^X6lhpfkg3F*KD)aw3W()RySU+l&B{1??huk?iTQ4$?c ze?d|gQAF0DESy^l`yKhOA&`=NOx2vjN|h}@zTPMcYSNJsu+F-+k@n{*%wBsIxMRd{PS;TC`09BgE$qG?p0*=XXr&(BGoWCfyNO4> zxc)SK_<#Tx(mH+Zb-Lle-yH2ZOzwJXLu-+Q_1G!_1Lx?vjIQ*3oyaBaf+xnb?2wnz z85?z}#}ZDV!^;oU>0wHhk2-nezB95!SD4OGFZg)?@uMYF9N%4An>FACn~~Gm_c%L_~N7g{&TM+epW8JaW~l*8N`C&)vg6z(POfW%)0_RMX-{px11MzguQ zvLnY_nsB0>-(X71R$9NV0Q0&vMZ4!HEKM85P#@5Q_1~YMam-`a{xTOA7n1mj zl8OVJ1py1>ZM$6*mS&B@Ob3P*TEBe>6x4aH{l7Sq0qK1Xvp_UJ&)-vCli>xTDsqL} zE4x6*%uLXeMG!9Aqg8z^qea>eLbN`?E)eI{6$z+Gopt@=#EKJ_wicRkxDi=7KkZl9 zZUNN4bVW6V-Q7c`=n1K%Y3j_*0^?ugZT+77hZ4VKWz2Bchzj4VnIie3FP3!gzCo@S zd-?J&>=|uX(X(@G^9*R-ORo6t@}+=WNbkdZdurKcV`x4~uF%W6x|~e_qt3nZS}L!Z zz6P+p`41;%UHO@tWV!=Y5 z37=bLC0P_ zn6)4BTwN8V0S)bgEsg@HSGx#S=iGU$epjAWI)vf~{hmiKJt0OnUPw=_!%-V0pr=CH_oaJDXq(NpX`*$6P*06`*1JL~uPH(t zmsSm8xBQeXVdr5$J$mMLpG&kB$DHjpxP4B%)^Rz6- zaJWk|njDpEVhNg~(4HeF0(6DBKeP&5*ku^7L%eDxjQRKbQY|8{RA;0n!(Nkdf2uU+ z+n48UpEm9eZFqDcvXeL`<8mjrf9u++ISd}oH!%@tIG%7q)OM5Cm`lH!OPC2z5=AIg z@0BqX;5rCC8BrCmQ@kp)YS2It_rzFg4T2U>%DPkq$i=JdG#n?W<>8P~!WTUUr$N~j z6VaKFNZ$6A6L8XC?4ngOoeI7K2oI>^9OQY%(mX8+4zcBjJC$i4NSF||{?e*4&KYCu zBq!j=LHw*M_z*Y&a?yc0pbJ9dup%iS5D#-rO7mqy=UEdZj9)bd;!S zki`)w_#EV=se4%Tr?6e>R;Boxx+*&f54fiqLkZd^O=lqnL6Pbz&rCVP%1r^IRGooy zhVsP{<~Wp>WqGdIVpeG#RH$%av__%SNp^t>FR?RO53!pB<(!w?a+;Lw!L^_4*aVhO z7R+sIo>rqLANT}9Re9W4QeK+CLNA1J5N_IjJ&3xZp-Utwe;LDey@IZxRZ(FhP!}!+ z3rv4u(HB4w2o=Q5@vK}tlx%)gQKy>pSoD)n0Gdej-%N!rTo*oAd?T9DaM%mD1$@DQ zUt_^OVk3YXR7G95w2$oq7hM!e65gC28>$;iNM|NuRqd zkfN)iEDxzvC0$*+Lb}`POZRfA-=Qe%P`~|VR&g(MN5dl~&e!9RM8+^C}}Wvg61SxSUJ z>uCPNQSp!SgREy?e?7V4?yh+X;;tFZG$^SjnG+==M^*-1zq#?P_m3MZ$F~*|(kf~=9z}W1LMIH zcCpkJztMt<(tz;pB9-dTle2dCdYFmmP*0jMOHjl-y7SbvqxWJ*kN2E8UQ(tufgxU4 z4qYKg3j6vxYrVuK&HHvkc-Xiy1#x*ghjV@K2t>%Cu&C&JEhX%*}$%9Lm*cfZukhZ}0YZpy8yFOO+=O|6l<`p*Vx=dG)7yeFh zRW0=2l+(1n@0WZtDN_vTWVDmp$#^eGyqB%m%fVMyM8AgRZ6H1~HLWV3Xz<61tL@8| z-wQF765HY4%33IG`26|(qc-@R)G}rGq1F82n=KWWznV%JT>u*q9dpf2-nl8I82?targ?LZZ|%nD2XTTdb<9W$dz+BAr7P?5;q&+iLM-vlI1vjydk8jZnTb}j?y_LukU`?sFmYBPp9HWco|Jf$nU+Dhh>q(b8My<`1; zar+6?0#7ONHGm7L*4<58$H>+#NfHv*JuaicMrGBpHEa4%j(7%#Q;=t}%8%{s82its zi=h=?kE{F=6hskw3+Gf|Wn{ZEM&kD+=0Q|c)V-@+79TRxRy&atWTXO5#ev4yITH7l zzaHm1ylFbF@`^Kp?T+gNx2;2j(kGgy=1FICjO_h8*EcrrT+q69(Q_pwEJ%dC@gp}x({b#n9XXn8xQ|NF6mAB!Ki1-#A@oHP*F+?oU!uxTBj6*U@7z94n^ zACFx<#&WjAjhSP=@IqK|2CS8HLiWm1`n8o6=auO>*B4XOf33M*8x_Fk za}NNM18$0@+7y+vrb=K79MBf5&VaqD3^lW zkGkwype2yU^mXl@b|uf%W0AR_;=-cdMoIToQ?FU4UDye%sWpHLXTN)9HBmYexBj-r zW6LUAssj3s33~VcH8#5YeNOf{;|9%?>f@BqT#sU8ermvmS1mM z^W|`H!)N8pUW+N#@er(Vy+UxZbVV)q`@_5UF7Iu4wx%>G_)J;q>PE zAz8tV42QhFe|K4#nL+QoOB>oMv+p(=KbGvi^@>e9vgL=%HZip?L%a$? zTkak0Yc9K=^Tq$iuDazxlGz)*A2lRJj^6RLXb5ED9!m~~ymG_6pdx!m$zMr!KkvMm z7A`*%Y-c0>w*0!mh8}g4JDCpqybt3iu4%5wuHX2vDrNZosggToeUFCp*k?EJQcrDo zG)w(r>iwOL3L+bhFTYvXNt-M0sr%MEs7VREwrlsp%_$u={fBp7;w8LTQ~&NA9ehb7 zWqySW6d7kAS|)FMVLu zv6$aRLi(@B3u1^ppMDfT9}X zvvQcQM~{Mc?o8P5&*HcrwH*{h8f1@$&ii8)Xfm2kMgD!}f!Xve!NI}fj6A{m=ZlYV zCQ_!-SFk9b3#@O|ZO{JOQ*x(nrj5;;svXl!_}s~GTAVn2n>=1fZu)xM+)&{GQd7;Q#gQB+@{^?j&IMD;=( znUJKod&D>7<2zwRPS`9%f#4TA@0GfuLTiYQ+yC%?uU?p)KjEw(HLm%e+r~BqrqX2g z#ffv9)t%`+q1WtwWW1h!bzTsq%G}#VRMAwI+?CN5ah z_rN(`sRMgrGF-nWuXrwAC6VMDnc6ICKUrN30uzg``z)Y+mZ^7#=S-fne~^;Om0 z9`z^VikFWceFKR-IH1b*jvR7K5%LsZGrr%y}wa#lge z+&aCV(m0raDC|JDYCk+bTCd)i!xt#T(&Ui<`ddy{t-7u1@%}hCsE_1xKR|#?Zim0y z+RK)w#^q^kR#NQEx$LaS^Eg8g+*kEYn$eA#-jLg_@t!MQtK zk1ur+^QwSHlc$0@Oh%LgdMIDyWFi%^Z>E(AR3?=vc&-p zgvE~KVlGv>DRO55Y%GS|39wHw>|}sFgJ9X$7ugmB3-@>g6^XFmijR1Rw1hC>v<2#~ zfjWtFMFYS?4g1iPV@2I~Co{y;GNIx6=qQC^$M|x*WAQT9!LA7>UAlEPQ-`MA63w$j5Mp%cZv= z(OW|H+XX}m#@~lnvoCEvKd|ZwD7J`;h-x7`O452r2dyF;5K!&@~9Ow0Tp*AcC2|h8S$j@L>k=zx-j2^a+TzD3?K*4};lp+?~Ch Ju1IB({|EC_!h-++ literal 9168 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 literal 7618 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 diff --git a/third_party/test/golden_widget/flutter_logo.string.ltr.png b/third_party/test/golden_widget/flutter_logo.string.ltr.png index e4402865634cfd5469cab823e5056404bd347fb8..7e70b9565dee51aef6a52f03b7b7119a82c15361 100644 GIT binary patch literal 3411 zcmeH{`CC(G7RTQNlnfY2SY)e)B!hs`qAgN^hTMrM2?!b^iZW~p2!bpM%9cuoLMJ3s zmQg?uQYcGNS`btE6n%nehfw#z6h$#e4NK69F@z9`s6FYwQQlwji~Cw0;`> zLzVK$W6i_pzU9-IG!U|KRvh@NJJ9~!^QNS-mOb7$g>#1YwftY>n`6FQyRbpN^o8g_ z;4=nV#8QW?z@3?bqF2_%FXeemW8d4wgw1K#e~{HLQvTC01AQ*~lenfB4r8U7L6 z7CRgsdjV-loW(x)S=3A||&Ek^r z=0cUo8u`*ObiHH|H97!jDz!%WZWwYD1E2u-7l0)b5G|rO5`aDcs{zbN05}4W0{F}X zN*9r7Kxmmc0V6`yfhvS+chcb$+ihLZHd-KZ%z-2uA;~@{ zlY$8l&mMr<1fZu)p#Zi4_|gQ1oeX$1-({)OO*vE>Rp~va?0fF#YsbD{xQyW)3nA?A zMG~bT_R7-p6!Gt0x6AL}Qv2y}JR-~_oV!m==ihedxzD(q`=Y##Q!{$qoFB{bahayel?6Jg(F16SS9HHM`%UCcpy+vZhf=QnY4{PgRem3ob4 z)b^LF>1mG^jQ_s2sOO05Efl%n12H0@ILdE9eL-oJ!5FK1VB>jSbnm(}h3R7$eJ<5V zzx~>FspAKKJ}RS*Q-&$c)%PKJmoJ43K9(ReklS;VJiFzlA&Hw-#;| z&Ac%WUa8bIwp2}_exmT*X#ZCU9UmCp-1uogH&jKt^NpA!3?hTU@fCzTy^7qxEiBN z*3tvP4MeGgBy5AFR7H4`Poz8<>;(%xlJ>aApS*K}vw45y2ghaGTt;LZ^?qpOTkWd= zQ0N2-t>+sFem$8pD)m3Rw8whfX^FF<>xWMs_Dv7did^=V4;0L%9S=DFEU%h?YiHu{ ziZ)+yMY2_^Kg)@bT?iZ3Z}lSMc})1~^~v=k8J{o`AM!FnwN)U{0R&>z zgk1+x4Fo6)*Un>CK0D8$(bSwzKW-?y!X?Bnt zA%jftT=9c7BWtq3OBppJzl3e3Gvmzuc_`YZrLTBMNLai`S mgdK&aD`&-l6$iip#uDYjYr3_J@>F}1AHg5*Vt2CQiv9o@we9f$ literal 3404 zcmeH|`&&|X9LK+hY%;A7Ej3qyNa}igGA~(E5#m7wGqu(-)6|-)P`fBzf@zY~25Lz% zua&deEZ1Y!R&!b|S47%W63Q%1%P2214ND``xzB0O{)+ki&q@lq9 z^G$3_5JK~LT+T*>=1>tLY$1LGq%<{aKU^@u#sD_D*tTR4Zj1zM-X7eyu+mVpJw$1M=DOs z_ZnF}I7;<8>8YsN!a0$BR!#SNO_H_y-wBEeG<)pF7r67}!6S+7-F$gTOLvi=t)c&v z%6Me#wa>Lbi+b|}G$>?t%{uUZcfhGO_Tlq8nhh>koHx6iTRYd(@vS3AZgC&`i zDp`PdA( z+54hSDZ;20eRIT7kntM_Uo=pFuox!*2LXJ9gCYP_0BZpl09b#AuyPjw+X0AhPzb;g zfHQzpx-V+VhAj~|fGi`tbR=7a5gH2>#z<&JMF})e^--2|iZN{CQFWuZ83I$F6Lz)l>{0dN4s0dN5DoCRCN zdK420F|r{>t_4O2-3~z$?OAAfAV`lJ5m|GkB&399&s*!T#x)jHv6ozjUz5yzCjU+<{zYOSrA-b}@EnUK@% zD@opARW+lX_oZEPe9g6Gy6^PJ$vEs13OwtqBlDfLS34YdJ}HKK!=^`D=fpTcXu9H# zrNWps2(^znz4Vvs5j6nE!IUzFB{{P#MFM0O5KhuDGw=(8R+_cucF@mOV!G_}I znp4rT0^SjD)&!glOgK*@gArncIn^Da#op6zsrRCgna3oxlclSjbXe$T5RqWWmYwOd z7dog9tjX`R5C%Z1^K|Hg%VpJZ+BTuW>k*q2Slsc zZT>dOlKRNs0L-g@XdxE=1Rh(Cw-c6AvX zgB5S|1NC8e30t9rRfQ4h$xoJoHRTiF(t1Yf4;j>lpjc}6Flwe(b=w$0*OgI*iHk)V z`f)4Qzs9PVJ!@uej%H5jYNirG$ZwE!G)R=ob+D1udwD+bjB4|VRZ5iH!pHtPmGwdX6Vt4K=k>JY_v$GN_jin8Adu87K(vC&TzzPvX)RVP=?4EY4rdXok1uxWI PNw^z4zhKTqc1+ek!J+%< diff --git a/third_party/test/golden_widget/flutter_logo.string.png b/third_party/test/golden_widget/flutter_logo.string.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..fc9ffa27529c1c7d62c7faecff5822448e6a262e 100644 GIT binary patch literal 10130 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 literal 10330 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.string.rtl.png b/third_party/test/golden_widget/flutter_logo.string.rtl.png index 6c8dd292777c2640514e08b937b8d3d764a80b9e..e65700f87fa6172382fd53a21970ffacf71e87d1 100644 GIT binary patch literal 3496 zcmeHJ>0gsq7QP8lf+K}Qlk#KBhR7fcrF2}{03ikvs6Zz2(@H8TP=taYxUdf?#F~I? zqcXJ!LBWx+EQ-SfRFFaCIvW2_Tx+FuV=^~N1I5M$)O?WZfEKG`!7^P5(NHS@%;xRLB0iy+|^$5?@N z1O1uxE9onVR8Zl->v`=@zewL4GE{MPfK(l0A;`^ctRPEM?_fxAUH?F9WDSDWHJM7bj0C>A~5l?;~>91QuI+I zfyj9X&ezKkt`d>(EoJ6(L}74|1p%CJ!O5~c2RZsk(UU+BWMTp)2>d``27*=)cy9ue ztz6{rH-zIzkx5_@HqgZ@dU{t2vU3{=r;($sf9xBv*V&)*WvIjH^7Ak zf+RVBW`~J6dVy)E;6#jR=o}PT40k9e5RnaufnuOOWnplKIWiqp<$%T=G+KMGxqxto zcY{qy<@_Q-Rma-Dd9;ZYRvhB^bzJ0;*FB!i9`RQ-iVW>Ve(m(m;|tH9&OB)Dn5}MN z_u1UFzdjZkapRU!;*9P%6kjfVw3tpr(82u`6ehK$O>Awl`6 zUEF;+`9-l=_Qo_OPg8HHIYvT7IAfup`^{fhwA@ZeA8cteN8*`F@c-dbZm7cVu zIcxI@!uIAa+r;7u%)yvpjNT=z1dti*n;`2N-mA5whA4%;Mgmyg%NB;NI0_ zh9)nc3Sb^+{lrv8Q#N*#0B`SL)utVM*BzK@O>@p6>9pEFeUh;R2NUBsEuZpyXL#wk zykh)e{_;!&DK(iIcR49)DUBpX8*L$zBecb5-L%H~h zIelO=s4@7s>_8SVK=-TPe`dD*ti4a56HotTsVVQ54FV@AvChm%!fMIqg+ zP=-}raJo~?<L#l~$=kMv`lQJky_(pQiRabJt)OzVq9Ou=tTIH^r{`vx+8V zA%ty7faI81av$1~Y0k;viKWtW4=$Poc&6%=o-6YydX+KS29%>5cku`n+rAt+pO-eH z_0!2Z%5Cef6gDKR^jr^YUTND~G6}iuV*vqTqtcw3O8L~;WcS#SHdk7knM$BNRTZ3W zS5xZQIMQr+yU)34xHX5B9xt!7gcbX_P%~ee{ zCMuFsSLeIfF@b65CXBaGG^J`!P~LuO7<@9?;QB7S-!hd+{kE6{1vB+N7P&KGFk@`| zImYWJ9{`-ImFHj6RZ*4N&hO&blv#x#^iAg&(^8Qga}i_hzdi?!KlT|O#vO1E{m)ib zU!A*;V&Us^?3FVO2{Wx44095DA_cv}VVCZ0C)am&w;T2zl53T;jCYTp4lZ*ck_kj2 zH|6CQsaH3BY&qvI{)fxbMDgJC2o;TBRVk}9L_WMd`6OdiUtLSNwT{yWbW~AnXoc!4 zKkyIff1w~Pj1Sq~0||1mAvPeoH$2o{(8wU5xk_e+MDW^?VJZbB0FW9`*~W=w4}_*J z(W;w@MqI5(ar%^P-9w7ryym5nkhe(a4h~4YD~?1YQ0%|?KVPDA2#40zS_RfB0DsQ> YSB+27^+L(4GaIXiuXg~ihI=^kzdytZE&u=k literal 3490 zcmeHH`CF4$7QP7xX{-$&AR?fUunPi?;#kWPGYPAe41-9l3brT=5*4vw5t6T%N}^&& z#9>XrO3``70+KO?5lCw(%!;JJYAn)z}hiFuVjVYO51eg??1$7ohXy{ zwye2xdWP{OzdSY&mFf|`UHNEq zP+It{{!>1Qi;)e>m~0B-I5QD7K#aJt0N@1R2tWt`Yyesb0Gv>F0pI|DApy{tD1-%o zApmRuij|1uvKAw^9(IDAATg@uePn_wOz9{w04Qw)1(I_4l%Oz}Xakd=fcvv1KrsRe z3n+RB-T+Q|!vM%40D=lmdT9Xs3_zNh9a`$S< zf+9ilodS`5Gk}ODkchfSA(gE$q@ec>EHu8AL~gweI|B|()aVH@4HOf!mjOFQpwa}-jHJ;do{fVxl|Rnr-UxM1me`iG|O?&&xa7|>Gqbg;Fr zZ(<}YM;Sk(i5BU;nH$Ki^4T-gx6P7wvo=5O)DUq21#m;^gDY{55VOrIc`YXmP z*_u|_ye%pA;IUZw(4QAwKk1%2V#6PkgTVRUE$J8*`1D-v|9YmRhs<30Q`QQuN$rAF zpgl)8G#htAG_3x4P_SOR-2%NQu8b|d9xO)Y5-7YSR#TDp=o4fONmGNw*Z;_Vey?NN zcMz3@8d8`$q`49kTl6gvbbT0O_yGq;=KDDI>i|0=VK+WI3XeUrob1c+t9m)ul(~W zaYP6kM|lx4Mr_V({A93LLctwGmMD&;k7*)?Q~x z-!G9lK_BiXnrzC9zW@BvFHBz9_fr_%cWD=rxK_6t>$^J}4^6xqMr6ZLLG;M@XZefz zX-QpEgZ5!wMe~Qg|9m&7LDg#s0}HeH2c8LZ;~HT`lI~J*+UrBE6*7Ns0YkPCZM6k2 z2ft`}+eK?p)oY*r+N6w`=V#DNwSPgCV{w}9Y>OQ*_K z)QY~YarQ$|=io?OrNvY=K`FwCsP|HH-e#6Z$%pQV!qSqXabX$gxF-mW{-d+=?JE%J zHX0d7+-C8WS5453d7*`Y+-MRc?<=n!=wFO+2%Ye$rdl0r#;H_(a|c=$-_;AS3Sfi5*+;^Rmw^2RO`*gzb;1nv}cjs zzkaa!b$;%PMuE{}4aS{cCcV2H)&GI*p5t$^Y5rkQ{pH4V zT@HsEe8@=(V9Rm=X^|834S(d(`xeV=H(U)s2FG6t4)gyo6!jO&WW zXYBa{YiGiQ-bWA7GUvN*4jk+@fakqe{vNmJHS(2K!p+8;}1L#rBU%tb2U>j}+Fx-mWp!?z+yAC`si x;c2P`T6$a&8V$e^LbqUZc`a99xdKpux^YoYx0dT9P&g9x2 Date: Fri, 5 Aug 2022 11:22:57 -0700 Subject: [PATCH 453/512] handle PT values (#747) --- third_party/lib/src/svg/parser_state.dart | 23 ++++++++++++++++++---- third_party/lib/src/utilities/numbers.dart | 1 + third_party/test/xml_svg_test.dart | 5 +++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index 975b726b6c09..26c59e56c827 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -1028,6 +1028,16 @@ class SvgParserState { } } + /// The number of pixels per CSS inch. + static const int kCssPixelsPerInch = 96; + + /// The number of points per CSS inch. + static const int kCssPointsPerInch = 72; + + /// The multiplicand to convert from CSS points to pixels. + static const double kPointsToPixelFactor = + kCssPixelsPerInch / kCssPointsPerInch; + /// Parses a `rawDouble` `String` to a `double` /// taking into account absolute and relative units /// (`px`, `em` or `ex`). @@ -1048,18 +1058,23 @@ class SvgParserState { String? rawDouble, { bool tryParse = false, }) { - double unit = 1.0; + if (rawDouble == null) { + return null; + } + double unit = 1.0; // 1 rem unit is equal to the root font size. // 1 em unit is equal to the current font size. // 1 ex unit is equal to the current x-height. - if (rawDouble?.contains('rem') ?? false) { + if (rawDouble.contains('pt')) { + unit = kPointsToPixelFactor; + } else if (rawDouble.contains('rem')) { _compatibilityTester.usesFontSize = true; unit = theme.fontSize; - } else if (rawDouble?.contains('em') ?? false) { + } else if (rawDouble.contains('em')) { _compatibilityTester.usesFontSize = true; unit = theme.fontSize; - } else if (rawDouble?.contains('ex') ?? false) { + } else if (rawDouble.contains('ex')) { _compatibilityTester.usesFontSize = true; unit = theme.xHeight; } diff --git a/third_party/lib/src/utilities/numbers.dart b/third_party/lib/src/utilities/numbers.dart index 0e94f226a10f..23e2b4061242 100644 --- a/third_party/lib/src/utilities/numbers.dart +++ b/third_party/lib/src/utilities/numbers.dart @@ -15,6 +15,7 @@ double? parseDouble(String? rawDouble, {bool tryParse = false}) { .replaceFirst('em', '') .replaceFirst('ex', '') .replaceFirst('px', '') + .replaceFirst('pt', '') .trim(); if (tryParse) { diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart index 0f891ad480f7..2d8992cb0209 100644 --- a/third_party/test/xml_svg_test.dart +++ b/third_party/test/xml_svg_test.dart @@ -427,4 +427,9 @@ void main() { }); }); }); + + test('Handles pt values', () { + final TestSvgParserState state = TestSvgParserState(); + expect(state.parseDoubleWithUnits('1pt'), 1 + 1 / 3); + }); } From a00a31ee9891aa528099424d338e269c263fbdc2 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 5 Aug 2022 11:23:51 -0700 Subject: [PATCH 454/512] bumps --- third_party/CHANGELOG.md | 4 ++++ third_party/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index f47c07003684..00dcddfaa6d6 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 1.1.3 + +- Handle `pt` values. + ## 1.1.2 - Update path parsing/drawing dependencies to fix arc parsing bug. diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 9e8b5d41d3d7..098e8c70ebbd 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 1.1.2 +version: 1.1.3 dependencies: flutter: From 715b06326914b0419ac5d7bb143b9f0cee456bcc Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 17 Aug 2022 11:40:36 -0700 Subject: [PATCH 455/512] Default image width/height correclty (#750) --- third_party/CHANGELOG.md | 4 ++++ third_party/lib/src/svg/parser_state.dart | 12 +++++------- third_party/pubspec.yaml | 2 +- third_party/test/svg_parsers_test.dart | 16 ++++++++++++++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 00dcddfaa6d6..9b0d6c27c5ca 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 1.1.4 + +- Handle default image width/height properly. + ## 1.1.3 - Handle `pt` values. diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index 26c59e56c827..79d930f96b1d 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -521,15 +521,13 @@ class _Elements { parserState.attribute('y', def: '0'), )!, ); + final Image image = await resolveImage(href); final Size size = Size( - parserState.parseDoubleWithUnits( - parserState.attribute('width', def: '0'), - )!, - parserState.parseDoubleWithUnits( - parserState.attribute('height', def: '0'), - )!, + parserState.parseDoubleWithUnits(parserState.attribute('width')) ?? + image.width.toDouble(), + parserState.parseDoubleWithUnits(parserState.attribute('height')) ?? + image.height.toDouble(), ); - final Image image = await resolveImage(href); final DrawableParent parent = parserState._parentDrawables.last.drawable!; final DrawableStyle? parentStyle = parent.style; final DrawableRasterImage drawable = DrawableRasterImage( diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 098e8c70ebbd..aeaa3a40e583 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,7 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. homepage: https://github.com/dnfield/flutter_svg -version: 1.1.3 +version: 1.1.4 dependencies: flutter: diff --git a/third_party/test/svg_parsers_test.dart b/third_party/test/svg_parsers_test.dart index 406161d30ac8..9ca75d9f3e3a 100644 --- a/third_party/test/svg_parsers_test.dart +++ b/third_party/test/svg_parsers_test.dart @@ -1183,4 +1183,20 @@ BAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" x="1ex" y="0.5ex" width="2ex" height="1.5ex" / expect(circle.style.stroke!.strokeWidth, 5); expect(circle.style.stroke!.strokeMiterLimit, 8); }); + + test('Defaults image height/width when not specified', () async { + // 1x1 PNG image from png-pixel.com. + const String svgStr = ''' + + +'''; + + final SvgParser parser = SvgParser(); + final DrawableRoot root = await parser.parse(svgStr); + + expect(root.children.length, 1); + final DrawableRasterImage image = root.children.first as DrawableRasterImage; + expect(image.size!.width, image.image.width); + expect(image.size!.height, image.image.height); + }); } From 78b325e5beffd70aafdd88c61db5e6fc8058aaf9 Mon Sep 17 00:00:00 2001 From: Joachim Nohl <43643339+nohli@users.noreply.github.com> Date: Tue, 6 Sep 2022 16:36:04 +0200 Subject: [PATCH 456/512] Update pub.dev links (#767) Co-authored-by: Daniel Flores Medina <78251680+Dev-dfm@users.noreply.github.com> Co-authored-by: Daniel Flores Medina <78251680+Dev-dfm@users.noreply.github.com> --- third_party/pubspec.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index aeaa3a40e583..40606f71eb58 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -1,6 +1,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. -homepage: https://github.com/dnfield/flutter_svg +repository: https://github.com/dnfield/flutter_svg +issue_tracker: https://github.com/dnfield/flutter_svg/issues version: 1.1.4 dependencies: From 20b909f99f6bc1ba6816ead8fe1838dd7e5c7439 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 9 Sep 2022 10:09:46 -0700 Subject: [PATCH 457/512] Colors (#773) * be more permissive about color strings * fix test * update goldens --- third_party/CHANGELOG.md | 4 ++++ third_party/lib/src/svg/parser_state.dart | 8 ++++++-- third_party/lib/svg.dart | 5 +++-- third_party/pubspec.yaml | 2 +- third_party/test/colors_svg_test.dart | 5 +++-- .../test/golden_widget/columns_and_rows.png | Bin 23184 -> 25764 bytes .../test/golden_widget/flutter_logo.asset.png | Bin 10130 -> 10330 bytes .../golden_widget/flutter_logo.memory.png | Bin 10130 -> 10330 bytes .../golden_widget/flutter_logo.network.png | Bin 10130 -> 10330 bytes ...go.string.color_filter.blendmode_color.png | Bin 9032 -> 9168 bytes .../flutter_logo.string.color_filter.png | Bin 7518 -> 7618 bytes .../golden_widget/flutter_logo.string.ltr.png | Bin 3411 -> 3404 bytes .../golden_widget/flutter_logo.string.png | Bin 10130 -> 10330 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 3496 -> 3490 bytes third_party/test/svg_parsers_test.dart | 3 ++- 15 files changed, 19 insertions(+), 8 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 9b0d6c27c5ca..6f683e14dc10 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 1.1.5 + +- More permissive about color strings. + ## 1.1.4 - Handle default image width/height properly. diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart index 79d930f96b1d..e9a4a5e60472 100644 --- a/third_party/lib/src/svg/parser_state.dart +++ b/third_party/lib/src/svg/parser_state.dart @@ -792,7 +792,7 @@ class SvgParserState { this.theme, this._key, this._warningsAsErrors, - ) + ) // ignore: unnecessary_null_comparison : assert(events != null), _eventIterator = events.iterator; @@ -1796,7 +1796,11 @@ class SvgParserState { return namedColor; } - throw StateError('Could not parse "$colorString" as a color.'); + // This is an error, but browsers are permissive here, so we can be too. + // See for example https://github.com/dnfield/flutter_svg/issues/764 - a + // user may be working with a network based SVG that uses the string "null" + // which is not part of the specification. + return null; } } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index d48ae3953925..43daf847eb5d 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -780,8 +780,9 @@ class _SvgPictureState extends State { final SvgTheme? defaultSvgTheme = DefaultSvgTheme.of(context)?.theme; final TextStyle defaultTextStyle = DefaultTextStyle.of(context).style; - final Color currentColor = - widget.theme?.currentColor ?? defaultSvgTheme?.currentColor ?? const Color(0xFF000000); + final Color currentColor = widget.theme?.currentColor ?? + defaultSvgTheme?.currentColor ?? + const Color(0xFF000000); final double fontSize = widget.theme?.fontSize ?? defaultSvgTheme?.fontSize ?? diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 40606f71eb58..4e7ea31e286e 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 1.1.4 +version: 1.1.5 dependencies: flutter: diff --git a/third_party/test/colors_svg_test.dart b/third_party/test/colors_svg_test.dart index 65aff31183e5..031de49cf163 100644 --- a/third_party/test/colors_svg_test.dart +++ b/third_party/test/colors_svg_test.dart @@ -48,7 +48,8 @@ void main() { testSvgParserState.theme.currentColor); expect(testSvgParserState.parseColor('currentcolor'), testSvgParserState.theme.currentColor); - expect( - () => testSvgParserState.parseColor('invalid name'), throwsStateError); + + expect(testSvgParserState.parseColor('invalid name'), null); + expect(testSvgParserState.parseColor('null'), null); }); } diff --git a/third_party/test/golden_widget/columns_and_rows.png b/third_party/test/golden_widget/columns_and_rows.png index 34053145e281c2d6bf83eb6acc305fd547a1555f..d4baaddf86b636c9e296dce515657b0d4ff1654e 100644 GIT binary patch literal 25764 zcmbq*2UJu`v+f`QDgvS;0U45_0wNj7Dl%jQlqeucB!lEMpeUdSLy#<>WR#pUl0lL% z63CU(Q-TkbH6ud|b}yd&6L~FiEldPaHlk4#`?l z8zN`+w4Z*J5`Rq%dq~nvn{umT{4s9x^9+_`?wt1fer0$W`?p(ZQhFn8x9gT=+3B?H zcw^nR?Q0Mcl_`4L8p=y}bEFBIo&qcM7E6jEPc=Vd3&* z7m}NqVwy2XdWxYc{O~Qoy*BNmjXYYI`%@2r41z!{PX)>W?7R}}G+w;^Il|7~VeP^C zwDSI;Y7uQ#Y4Yh06^ASPruR9g-Y6U6JZ-}1GQ`g(I~2RnQ(^6lg+;5^JA206Af20* zs_j7Cf^gHJBxCDEW@XruJeIW155;#iI;GOSOuZX#uh1tZI0x&k6(@(WSbxP*bMEfx zf1#~yx=nAv=cmXjz4DpWXvL95Mu?-?=^#Ju3|fFD)Q9*Cv)NEbWW zN_D;BI==CDt5~QNYQ^pWTTy?C#LoP%@03yQu9Q;&@sYy_G&0TaVjXXPxx?HwO>MA# zWJ^-{$1U&dzEIeo$1onhp}H-!lAYS5F};GY)&6@hk?~kYrbL@-Lw;*WFad#uHGT8I z1naiF5PO~)8w-g%7FU}z4uvZZAQ@N-VS-7#S7Mr5LeE?=AcgesJdJP`56w!2@cq<$UI1z zlt!hWbiGI-yfQfPvzHKw)0h1w>=yqsOg6a#}b z#(^ELe|xRcLRNa`4r8XM-@z2sG-A^;>i!uRqYv0wYQ5rsVvV0|=ybpD8;89%u6mrM zx30lP$tW+uEE|>xHWUt=w@fQ$^b`e1Hxi71(3o3TikyQLzJ(gMgXP?-9(BbZVR^AZ zFr(niG2i>=`skzd~C#Hp{s#xkvl+E*wok;zS{D3_tX1u03IaSwfq` z_q?nR99WT6+h_+{!KgsT=58Kv;Bo88Vb9^v@1tn#NO)0+E&uCxl0|9g;oiOQI*QZZ z7){Hr3i6MzN@|xy|2kvvLnQ+*=7RyHAIcZK%m=TdiWScrXBx=
t*%$@hS!C00^JF1i0X6&Mk*F7tCFiuKoiJG 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�u9vbX{zc#lGCFlb@L2Onwq@UnkgLn5^=% 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 OceTRWk)O+RKm31$8ZSuz literal 10130 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 diff --git a/third_party/test/golden_widget/flutter_logo.memory.png b/third_party/test/golden_widget/flutter_logo.memory.png index fc9ffa27529c1c7d62c7faecff5822448e6a262e..7b88eeff0280f9170d14a57356ba73fe922ededb 100644 GIT binary patch literal 10330 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 OceTRWk)O+RKm31$8ZSuz literal 10130 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 diff --git a/third_party/test/golden_widget/flutter_logo.network.png b/third_party/test/golden_widget/flutter_logo.network.png index fc9ffa27529c1c7d62c7faecff5822448e6a262e..7b88eeff0280f9170d14a57356ba73fe922ededb 100644 GIT binary patch literal 10330 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 OceTRWk)O+RKm31$8ZSuz literal 10130 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 diff --git a/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png b/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png index d46b6ded9b7b4cbe558dcf475ae18bbc7c50b096..6b12ded3f96226de0bef22a1502715fdd3b1c757 100644 GIT binary patch literal 9168 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 Ju1IB({|EC_!h-++ diff --git a/third_party/test/golden_widget/flutter_logo.string.color_filter.png b/third_party/test/golden_widget/flutter_logo.string.color_filter.png index 0f02fbfe18a983b802848cc90e92329fd572b611..d80af0975390b8ab1d09108ebb7d44780e376578 100644 GIT binary patch literal 7618 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 literal 7518 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 diff --git a/third_party/test/golden_widget/flutter_logo.string.ltr.png b/third_party/test/golden_widget/flutter_logo.string.ltr.png index 7e70b9565dee51aef6a52f03b7b7119a82c15361..e4402865634cfd5469cab823e5056404bd347fb8 100644 GIT binary patch literal 3404 zcmeH|`&&|X9LK+hY%;A7Ej3qyNa}igGA~(E5#m7wGqu(-)6|-)P`fBzf@zY~25Lz% zua&deEZ1Y!R&!b|S47%W63Q%1%P2214ND``xzB0O{)+ki&q@lq9 z^G$3_5JK~LT+T*>=1>tLY$1LGq%<{aKU^@u#sD_D*tTR4Zj1zM-X7eyu+mVpJw$1M=DOs z_ZnF}I7;<8>8YsN!a0$BR!#SNO_H_y-wBEeG<)pF7r67}!6S+7-F$gTOLvi=t)c&v z%6Me#wa>Lbi+b|}G$>?t%{uUZcfhGO_Tlq8nhh>koHx6iTRYd(@vS3AZgC&`i zDp`PdA( z+54hSDZ;20eRIT7kntM_Uo=pFuox!*2LXJ9gCYP_0BZpl09b#AuyPjw+X0AhPzb;g zfHQzpx-V+VhAj~|fGi`tbR=7a5gH2>#z<&JMF})e^--2|iZN{CQFWuZ83I$F6Lz)l>{0dN4s0dN5DoCRCN zdK420F|r{>t_4O2-3~z$?OAAfAV`lJ5m|GkB&399&s*!T#x)jHv6ozjUz5yzCjU+<{zYOSrA-b}@EnUK@% zD@opARW+lX_oZEPe9g6Gy6^PJ$vEs13OwtqBlDfLS34YdJ}HKK!=^`D=fpTcXu9H# zrNWps2(^znz4Vvs5j6nE!IUzFB{{P#MFM0O5KhuDGw=(8R+_cucF@mOV!G_}I znp4rT0^SjD)&!glOgK*@gArncIn^Da#op6zsrRCgna3oxlclSjbXe$T5RqWWmYwOd z7dog9tjX`R5C%Z1^K|Hg%VpJZ+BTuW>k*q2Slsc zZT>dOlKRNs0L-g@XdxE=1Rh(Cw-c6AvX zgB5S|1NC8e30t9rRfQ4h$xoJoHRTiF(t1Yf4;j>lpjc}6Flwe(b=w$0*OgI*iHk)V z`f)4Qzs9PVJ!@uej%H5jYNirG$ZwE!G)R=ob+D1udwD+bjB4|VRZ5iH!pHtPmGwdX6Vt4K=k>JY_v$GN_jin8Adu87K(vC&TzzPvX)RVP=?4EY4rdXok1uxWI PNw^z4zhKTqc1+ek!J+%< literal 3411 zcmeH{`CC(G7RTQNlnfY2SY)e)B!hs`qAgN^hTMrM2?!b^iZW~p2!bpM%9cuoLMJ3s zmQg?uQYcGNS`btE6n%nehfw#z6h$#e4NK69F@z9`s6FYwQQlwji~Cw0;`> zLzVK$W6i_pzU9-IG!U|KRvh@NJJ9~!^QNS-mOb7$g>#1YwftY>n`6FQyRbpN^o8g_ z;4=nV#8QW?z@3?bqF2_%FXeemW8d4wgw1K#e~{HLQvTC01AQ*~lenfB4r8U7L6 z7CRgsdjV-loW(x)S=3A||&Ek^r z=0cUo8u`*ObiHH|H97!jDz!%WZWwYD1E2u-7l0)b5G|rO5`aDcs{zbN05}4W0{F}X zN*9r7Kxmmc0V6`yfhvS+chcb$+ihLZHd-KZ%z-2uA;~@{ zlY$8l&mMr<1fZu)p#Zi4_|gQ1oeX$1-({)OO*vE>Rp~va?0fF#YsbD{xQyW)3nA?A zMG~bT_R7-p6!Gt0x6AL}Qv2y}JR-~_oV!m==ihedxzD(q`=Y##Q!{$qoFB{bahayel?6Jg(F16SS9HHM`%UCcpy+vZhf=QnY4{PgRem3ob4 z)b^LF>1mG^jQ_s2sOO05Efl%n12H0@ILdE9eL-oJ!5FK1VB>jSbnm(}h3R7$eJ<5V zzx~>FspAKKJ}RS*Q-&$c)%PKJmoJ43K9(ReklS;VJiFzlA&Hw-#;| z&Ac%WUa8bIwp2}_exmT*X#ZCU9UmCp-1uogH&jKt^NpA!3?hTU@fCzTy^7qxEiBN z*3tvP4MeGgBy5AFR7H4`Poz8<>;(%xlJ>aApS*K}vw45y2ghaGTt;LZ^?qpOTkWd= zQ0N2-t>+sFem$8pD)m3Rw8whfX^FF<>xWMs_Dv7did^=V4;0L%9S=DFEU%h?YiHu{ ziZ)+yMY2_^Kg)@bT?iZ3Z}lSMc})1~^~v=k8J{o`AM!FnwN)U{0R&>z zgk1+x4Fo6)*Un>CK0D8$(bSwzKW-?y!X?Bnt zA%jftT=9c7BWtq3OBppJzl3e3Gvmzuc_`YZrLTBMNLai`S mgdK&aD`&-l6$iip#uDYjYr3_J@>F}1AHg5*Vt2CQiv9o@we9f$ diff --git a/third_party/test/golden_widget/flutter_logo.string.png b/third_party/test/golden_widget/flutter_logo.string.png index fc9ffa27529c1c7d62c7faecff5822448e6a262e..7b88eeff0280f9170d14a57356ba73fe922ededb 100644 GIT binary patch literal 10330 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 OceTRWk)O+RKm31$8ZSuz literal 10130 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 diff --git a/third_party/test/golden_widget/flutter_logo.string.rtl.png b/third_party/test/golden_widget/flutter_logo.string.rtl.png index e65700f87fa6172382fd53a21970ffacf71e87d1..6c8dd292777c2640514e08b937b8d3d764a80b9e 100644 GIT binary patch literal 3490 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 YSB+27^+L(4GaIXiuXg~ihI=^kzdytZE&u=k diff --git a/third_party/test/svg_parsers_test.dart b/third_party/test/svg_parsers_test.dart index 9ca75d9f3e3a..2c20fd2cb1bd 100644 --- a/third_party/test/svg_parsers_test.dart +++ b/third_party/test/svg_parsers_test.dart @@ -1195,7 +1195,8 @@ BAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" x="1ex" y="0.5ex" width="2ex" height="1.5ex" / final DrawableRoot root = await parser.parse(svgStr); expect(root.children.length, 1); - final DrawableRasterImage image = root.children.first as DrawableRasterImage; + final DrawableRasterImage image = + root.children.first as DrawableRasterImage; expect(image.size!.width, image.image.width); expect(image.size!.height, image.image.height); }); From b2e20fccdddfd3e2f0e8324655c5603411656f0f Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Sat, 22 Oct 2022 13:25:39 -0700 Subject: [PATCH 458/512] Strokes with zero width should not be painted (#798) Fix #797 --- .../example/assets/simple/zero_width_strokes.svg | 3 +++ third_party/golden/simple/zero_width_strokes.png | Bin 0 -> 619 bytes third_party/lib/src/vector_drawable.dart | 5 ++++- 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 third_party/example/assets/simple/zero_width_strokes.svg create mode 100644 third_party/golden/simple/zero_width_strokes.png diff --git a/third_party/example/assets/simple/zero_width_strokes.svg b/third_party/example/assets/simple/zero_width_strokes.svg new file mode 100644 index 000000000000..36e37d8d7b95 --- /dev/null +++ b/third_party/example/assets/simple/zero_width_strokes.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/third_party/golden/simple/zero_width_strokes.png b/third_party/golden/simple/zero_width_strokes.png new file mode 100644 index 0000000000000000000000000000000000000000..c27fed45024c3d41be01e5e67e8ec08b96073ddf GIT binary patch literal 619 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_mZkPZ!6KiaBpDZxlSBAaG#Agumr=Vh`>(Df&J*mYw#Dx$oa?#t%l#4h9@7 fqr?aagBIT4o2)%mwSV>j6AXi=tDnm{r-UW|Rn?0s literal 0 HcmV?d00001 diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 1ff13d6a6a12..03968c260086 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -1293,7 +1293,10 @@ class DrawableShape implements DrawableStyleable { canvas.drawPath(path, style.fill!.toFlutterPaint()); } - if (style.stroke?.color != null) { + if (style.stroke?.color != null && + (style.stroke!.strokeWidth == null || + (style.stroke!.strokeWidth != null && + style.stroke!.strokeWidth! > 0))) { assert(style.stroke!.style == PaintingStyle.stroke); if (style.dashArray != null && !identical(style.dashArray, DrawableStyle.emptyDashArray)) { From c11458171734bb1657f0c94983624373f7a86644 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Mon, 24 Oct 2022 10:24:30 -0700 Subject: [PATCH 459/512] Transform clip path when applied to a group (#794) * Transform clip path when applied to a group Fix #136, #343, #566 * Golden test added --- .../assets/simple/clip_path_transform.svg | 17 +++++++++++++++++ .../golden/simple/clip_path_transform.png | Bin 0 -> 5307 bytes third_party/lib/src/vector_drawable.dart | 4 ++++ 3 files changed, 21 insertions(+) create mode 100644 third_party/example/assets/simple/clip_path_transform.svg create mode 100644 third_party/golden/simple/clip_path_transform.png diff --git a/third_party/example/assets/simple/clip_path_transform.svg b/third_party/example/assets/simple/clip_path_transform.svg new file mode 100644 index 000000000000..80a791eb12a7 --- /dev/null +++ b/third_party/example/assets/simple/clip_path_transform.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/golden/simple/clip_path_transform.png b/third_party/golden/simple/clip_path_transform.png new file mode 100644 index 0000000000000000000000000000000000000000..9aa0955409a18a8015c519fa9e26bfc8a8331e76 GIT binary patch literal 5307 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 literal 0 HcmV?d00001 diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 03968c260086..985bab77ae2f 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -1098,6 +1098,10 @@ class DrawableGroup implements DrawableStyleable, DrawableParent { if (style?.clipPath?.isNotEmpty == true) { for (Path clipPath in style!.clipPath!) { + if (transform != null) { + clipPath = clipPath.transform(transform!); + } + canvas.save(); canvas.clipPath(clipPath); if (children!.length > 1) { From bd5377a01e820220da60cf3ea317603bb2ed8ab2 Mon Sep 17 00:00:00 2001 From: Feodor Fitsner Date: Mon, 24 Oct 2022 22:09:32 -0700 Subject: [PATCH 460/512] Apply image transform before translate and scale (#790) * Apply image transform before translate and scale * Added golden test * Fix SVG * Update image.png --- .../simple/image_transform_before_translate.svg | 5 +++++ third_party/golden/simple/image.png | Bin 693 -> 695 bytes .../simple/image_transform_before_translate.png | Bin 0 -> 675 bytes third_party/lib/src/vector_drawable.dart | 4 ++-- 4 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 third_party/example/assets/simple/image_transform_before_translate.svg create mode 100644 third_party/golden/simple/image_transform_before_translate.png diff --git a/third_party/example/assets/simple/image_transform_before_translate.svg b/third_party/example/assets/simple/image_transform_before_translate.svg new file mode 100644 index 000000000000..f74b1a25893b --- /dev/null +++ b/third_party/example/assets/simple/image_transform_before_translate.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/third_party/golden/simple/image.png b/third_party/golden/simple/image.png index a14ff426a01582502ef9bada94335e93eff71747..116280a365107c13fa007f4f86da98e8cdb55d4b 100644 GIT binary patch delta 245 zcmdnWx}9}`qjRFCi(^Q|oVRy3cC{FYI9xny^#A|qnPCMxd{fSxuw0sO;nAlJ6&BCt zeCGf0;{QALhPj+9O%4is^y~|JPWS)Onx7&wV`8C_h@*nQx!(%=_nqIE_4V)D$u?b_ zOpZYDiS;5dB*wqX==rVA(kqJ*Qw7fJ#?cD!)&-EaE7QT@0nE5X&uQ) Q`x$`1)78&qol`;+0LHOyk^lez literal 693 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q{hPZ!6KiaBp@8+I`p3NSdH{_#J4TJT}nxjqUvL!R!=XijrDy=L$CI)?vM z^XwSz_$UalFgfBS9+v)M=-=u$KjE0wS$|_k1rC-b2Li;I?~eOw=O<_V`uojuU0Rca z00&DWor#Lx`y0N$`MLF&y9Ll0F=tsC6$Ch#2oMJM*=KI@KX}v!rgZ1UsQdd@|5s)y zntk5DrDzV&<4?@yU%$8RK)>~W`Ih}Hg}lOqgM)|=8zM>$N!NypPRoq+e#-y^p00i_ I>zopr04t)dUH||9 diff --git a/third_party/golden/simple/image_transform_before_translate.png b/third_party/golden/simple/image_transform_before_translate.png new file mode 100644 index 0000000000000000000000000000000000000000..d1517c05ddaa61f2ed3b9daf6025e23a62b73839 GIT binary patch literal 675 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_mZyPZ!6KiaBquD&{!_GPnfVIfjRn*k;JQjN5Qma$gQ(XF50k?OEABPBuT8 zBigfbX6m21p0l%e*Vmt&w_(=#+oj)F{@pky$FSZ?W)E9&Vn}3`}PX44$rjF6*2U FngAK6j^6+P literal 0 HcmV?d00001 diff --git a/third_party/lib/src/vector_drawable.dart b/third_party/lib/src/vector_drawable.dart index 985bab77ae2f..28ae5a7b3088 100644 --- a/third_party/lib/src/vector_drawable.dart +++ b/third_party/lib/src/vector_drawable.dart @@ -1205,11 +1205,11 @@ class DrawableRasterImage implements DrawableStyleable { halfDesiredSize.height - scaledHalfImageSize.height, ); canvas.save(); - canvas.translate(offset.dx + shift.dx, offset.dy + shift.dy); - canvas.scale(scale, scale); if (transform != null) { canvas.transform(transform!); } + canvas.translate(offset.dx + shift.dx, offset.dy + shift.dy); + canvas.scale(scale, scale); } canvas.drawImage(image, Offset.zero, Paint()); if (scale != 1.0 || offset != Offset.zero || transform != null) { From 9e15bb80b37da9872c2681e94e5da95159adb7fd Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 25 Oct 2022 00:37:19 -0700 Subject: [PATCH 461/512] version bumps --- third_party/CHANGELOG.md | 5 +++++ third_party/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 6f683e14dc10..910b111e957c 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 1.1.6 + +- Fix transforms on image tags, clipPaths. +- Avoid painting zero-width strokes. + ## 1.1.5 - More permissive about color strings. diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 4e7ea31e286e..04cef40e66f0 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 1.1.5 +version: 1.1.6 dependencies: flutter: From 56ca1d3550f771ce5d17db69c7e8859047f10f09 Mon Sep 17 00:00:00 2001 From: Dawid Wysocki <62249621+TortillaZHawaii@users.noreply.github.com> Date: Tue, 25 Oct 2022 10:48:07 +0200 Subject: [PATCH 462/512] Fix typo (#799) --- third_party/lib/src/picture_provider.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart index bf46e3150bf2..bb6cb12d4700 100644 --- a/third_party/lib/src/picture_provider.dart +++ b/third_party/lib/src/picture_provider.dart @@ -422,7 +422,7 @@ abstract class PictureProvider { /// An immutable key representing the current state of a [PictureProvider]. @immutable class PictureKey { - /// Creates a new immutable key reprenseting the current state of a + /// Creates a new immutable key representing the current state of a /// [PictureProvider] for the [PictureCache]. const PictureKey( this.keyData, { From 078738d2f0cf890353c9a480bc5167c8675209c1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 18 Nov 2022 14:57:08 -0800 Subject: [PATCH 463/512] Start using VG (#782) Use vector_graphics. Flutter_svg 2.0! --- third_party/.cirrus.yml | 17 - third_party/CHANGELOG.md | 25 + third_party/example/.metadata | 28 +- .../example/ios/Flutter/Flutter.podspec | 18 - third_party/example/lib/main.dart | 9 +- third_party/example/lib/simple.dart | 28 +- third_party/example/macos/.gitignore | 1 + .../macos/Runner.xcodeproj/project.pbxproj | 29 +- .../contents.xcworkspacedata | 7 - .../xcshareddata/xcschemes/Runner.xcscheme | 22 +- .../AppIcon.appiconset/app_icon_1024.png | Bin 46993 -> 102994 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 3276 -> 5680 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 1429 -> 520 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 5933 -> 14142 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 1243 -> 1066 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 14800 -> 36406 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 1874 -> 2218 bytes .../macos/Runner/Base.lproj/MainMenu.xib | 4 + .../macos/Runner/Configs/AppInfo.xcconfig | 2 +- .../macos/Runner/DebugProfile.entitlements | 6 - .../example/macos/Runner/Release.entitlements | 6 - third_party/example/pubspec.yaml | 14 +- third_party/golden/dart.png | Bin 3651 -> 0 bytes .../deborah_ufw/new-action-expander.png | Bin 4655 -> 0 bytes third_party/golden/deborah_ufw/new-camera.png | Bin 5049 -> 0 bytes .../golden/deborah_ufw/new-gif-button.png | Bin 5167 -> 0 bytes third_party/golden/deborah_ufw/new-gif.png | Bin 3143 -> 0 bytes third_party/golden/deborah_ufw/new-image.png | Bin 4493 -> 0 bytes .../golden/deborah_ufw/new-mention.png | Bin 4420 -> 0 bytes .../golden/deborah_ufw/new-pause-button.png | Bin 4513 -> 0 bytes .../golden/deborah_ufw/new-play-button.png | Bin 4696 -> 0 bytes .../golden/deborah_ufw/new-send-circle.png | Bin 5591 -> 0 bytes third_party/golden/deborah_ufw/numeric_25.png | Bin 2053 -> 0 bytes third_party/golden/flutter_logo.png | Bin 2763 -> 0 bytes .../golden/noto-emoji/emoji_u1f600.png | Bin 9294 -> 0 bytes third_party/golden/simple/blend_and_mask.png | Bin 6005 -> 0 bytes .../golden/simple/blend_mode_devil.png | Bin 24137 -> 0 bytes third_party/golden/simple/clip_path.png | Bin 2618 -> 0 bytes third_party/golden/simple/clip_path_2.png | Bin 2271 -> 0 bytes third_party/golden/simple/clip_path_3.png | Bin 2691 -> 0 bytes .../golden/simple/clip_path_transform.png | Bin 5307 -> 0 bytes third_party/golden/simple/dash_path.png | Bin 794 -> 0 bytes third_party/golden/simple/dash_zero.png | Bin 775 -> 0 bytes third_party/golden/simple/ellipse.png | Bin 3847 -> 0 bytes third_party/golden/simple/empty_defs.png | Bin 492 -> 0 bytes third_party/golden/simple/empty_group.png | Bin 4013 -> 0 bytes third_party/golden/simple/equation.png | Bin 3060 -> 0 bytes .../golden/simple/fill-rule-inherit.png | Bin 5300 -> 0 bytes .../golden/simple/fill_inheritence_test.png | Bin 588 -> 0 bytes .../golden/simple/group_composite_opacity.png | Bin 6635 -> 0 bytes .../golden/simple/group_fill_opacity.png | Bin 5155 -> 0 bytes third_party/golden/simple/group_in_defs.png | Bin 1717 -> 0 bytes third_party/golden/simple/group_mask.png | Bin 2146 -> 0 bytes third_party/golden/simple/group_opacity.png | Bin 3772 -> 0 bytes .../golden/simple/group_opacity_transform.png | Bin 749 -> 0 bytes third_party/golden/simple/hidden.png | Bin 1960 -> 0 bytes third_party/golden/simple/href-fill.png | Bin 2021 -> 0 bytes third_party/golden/simple/image.png | Bin 695 -> 0 bytes third_party/golden/simple/image_def.png | Bin 1193 -> 0 bytes .../image_transform_before_translate.png | Bin 675 -> 0 bytes .../simple/implicit_fill_with_opacity.png | Bin 699 -> 0 bytes .../golden/simple/invalid_dash_array.png | Bin 2732 -> 0 bytes third_party/golden/simple/linear_gradient.png | Bin 1838 -> 0 bytes .../golden/simple/linear_gradient_2.png | Bin 763 -> 0 bytes ...gradient_absolute_user_space_translate.png | Bin 5718 -> 0 bytes ...gradient_percentage_bounding_translate.png | Bin 2046 -> 0 bytes ...adient_percentage_user_space_translate.png | Bin 2083 -> 0 bytes .../golden/simple/linear_gradient_xlink.png | Bin 4748 -> 0 bytes third_party/golden/simple/male.png | Bin 4057 -> 0 bytes third_party/golden/simple/mask.png | Bin 4953 -> 0 bytes .../golden/simple/mask_with_gradient.png | Bin 648 -> 0 bytes third_party/golden/simple/mask_with_use.png | Bin 633 -> 0 bytes third_party/golden/simple/mask_with_use2.png | Bin 1368 -> 0 bytes third_party/golden/simple/nested_group.png | Bin 4013 -> 0 bytes third_party/golden/simple/opacity_on_path.png | Bin 1443 -> 0 bytes third_party/golden/simple/radial_gradient.png | Bin 3267 -> 0 bytes ...gradient_absolute_user_space_translate.png | Bin 13507 -> 0 bytes .../golden/simple/radial_gradient_focal.png | Bin 12308 -> 0 bytes ...gradient_percentage_bounding_translate.png | Bin 7056 -> 0 bytes ...adient_percentage_user_space_translate.png | Bin 13092 -> 0 bytes .../golden/simple/radial_gradient_xlink.png | Bin 3267 -> 0 bytes .../simple/radial_ref_linear_gradient.png | Bin 7808 -> 0 bytes third_party/golden/simple/rect_rrect.png | Bin 2594 -> 0 bytes .../golden/simple/rect_rrect_no_ry.png | Bin 1731 -> 0 bytes .../golden/simple/stroke_inherit_circles.png | Bin 5710 -> 0 bytes third_party/golden/simple/style_attr.png | Bin 1085 -> 0 bytes third_party/golden/simple/text.png | Bin 457 -> 0 bytes third_party/golden/simple/text_2.png | Bin 892 -> 0 bytes third_party/golden/simple/text_3.png | Bin 431 -> 0 bytes third_party/golden/simple/text_4.png | Bin 1022 -> 0 bytes third_party/golden/simple/text_5.png | Bin 563 -> 0 bytes third_party/golden/simple/text_6.png | Bin 692 -> 0 bytes third_party/golden/simple/use_circles.png | Bin 2496 -> 0 bytes third_party/golden/simple/use_circles_def.png | Bin 1975 -> 0 bytes third_party/golden/simple/use_emc2.png | Bin 2494 -> 0 bytes third_party/golden/simple/use_fill.png | Bin 873 -> 0 bytes third_party/golden/simple/use_fill_test.png | Bin 718 -> 0 bytes .../golden/simple/use_opacity_grid.png | Bin 957 -> 0 bytes .../golden/simple/width_height_viewbox.png | Bin 2213 -> 0 bytes .../golden/simple/zero_width_strokes.png | Bin 619 -> 0 bytes third_party/golden/svg_currentcolor.png | Bin 4192 -> 0 bytes third_party/golden/text_transform.png | Bin 3457 -> 0 bytes third_party/golden/w3samples/aa.png | Bin 4862 -> 0 bytes third_party/golden/w3samples/alphachannel.png | Bin 4920 -> 0 bytes .../golden/wikimedia/Firefox_Logo_2017.png | Bin 23087 -> 0 bytes .../wikimedia/Flag_of_the_United_States.png | Bin 2379 -> 0 bytes .../golden/wikimedia/Ghostscript_Tiger.png | Bin 39026 -> 0 bytes third_party/golden/wikimedia/chess_knight.png | Bin 4744 -> 0 bytes third_party/lib/avd.dart | 348 --- third_party/lib/flutter_svg.dart | 5 - third_party/lib/parser.dart | 29 - third_party/lib/src/avd/xml_parsers.dart | 273 --- third_party/lib/src/avd_parser.dart | 74 - .../src/{picture_cache.dart => cache.dart} | 60 +- third_party/lib/src/loaders.dart | 287 +++ third_party/lib/src/picture_provider.dart | 982 --------- third_party/lib/src/picture_stream.dart | 442 ---- third_party/lib/src/render_picture.dart | 291 --- third_party/lib/src/svg/default_theme.dart | 41 - third_party/lib/src/svg/parser_state.dart | 1960 ----------------- third_party/lib/src/svg/parsers.dart | 220 -- third_party/lib/src/svg/theme.dart | 50 - .../lib/src/utilities/_compute_io.dart | 8 + .../lib/src/utilities/_compute_none.dart | 2 + third_party/lib/src/utilities/_file_none.dart | 3 + third_party/lib/src/utilities/compute.dart | 24 + third_party/lib/src/vector_drawable.dart | 1367 ------------ third_party/lib/svg.dart | 645 +----- third_party/pubspec.yaml | 20 +- third_party/test/cache_test.dart | 80 + third_party/test/colors_svg_test.dart | 55 - third_party/test/default_theme_test.dart | 214 -- third_party/test/error_test.dart | 37 - third_party/test/golden_svg_test.dart | 56 - .../test/golden_widget/circle.em_ex.png | Bin 10223 -> 10224 bytes .../test/golden_widget/circle.em_ex2.png | Bin 0 -> 10224 bytes .../test/golden_widget/columns_and_rows.png | Bin 25764 -> 25790 bytes .../test/golden_widget/ellipse.em_ex.png | Bin 6672 -> 6534 bytes .../test/golden_widget/ellipse.em_ex2.png | Bin 0 -> 6534 bytes .../test/golden_widget/flutter_logo.asset.png | Bin 10330 -> 10275 bytes .../golden_widget/flutter_logo.memory.png | Bin 10330 -> 10275 bytes .../golden_widget/flutter_logo.natural.png | Bin 25892 -> 25928 bytes .../golden_widget/flutter_logo.network.png | Bin 10330 -> 10275 bytes ...go.string.color_filter.blendmode_color.png | Bin 9168 -> 9344 bytes .../flutter_logo.string.color_filter.png | Bin 7618 -> 7599 bytes .../golden_widget/flutter_logo.string.ltr.png | Bin 3404 -> 3389 bytes .../golden_widget/flutter_logo.string.png | Bin 10330 -> 10275 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 3490 -> 3389 bytes .../test/golden_widget/line.em_ex2.png | Bin 0 -> 6500 bytes third_party/test/golden_widget/rect.em_ex.png | Bin 4071 -> 4070 bytes .../test/golden_widget/rect.em_ex2.png | Bin 0 -> 4070 bytes .../stick_figure.withclipping.png | Bin 20023 -> 20024 bytes third_party/test/loaders_test.dart | 31 + third_party/test/picture_cache_test.dart | 219 -- third_party/test/picture_provider_test.dart | 199 -- third_party/test/picture_stream_test.dart | 134 -- third_party/test/render_picture_test.dart | 59 - third_party/test/svg_parsers_test.dart | 1203 ---------- third_party/test/theme_test.dart | 88 - third_party/test/vector_drawable_test.dart | 150 -- third_party/test/widget_svg_test.dart | 372 +--- third_party/test/xml_svg_test.dart | 435 ---- third_party/tool/gen_golden.dart | 86 - 163 files changed, 696 insertions(+), 10069 deletions(-) delete mode 100644 third_party/.cirrus.yml delete mode 100644 third_party/example/ios/Flutter/Flutter.podspec delete mode 100644 third_party/example/macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 third_party/golden/dart.png delete mode 100644 third_party/golden/deborah_ufw/new-action-expander.png delete mode 100644 third_party/golden/deborah_ufw/new-camera.png delete mode 100644 third_party/golden/deborah_ufw/new-gif-button.png delete mode 100644 third_party/golden/deborah_ufw/new-gif.png delete mode 100644 third_party/golden/deborah_ufw/new-image.png delete mode 100644 third_party/golden/deborah_ufw/new-mention.png delete mode 100644 third_party/golden/deborah_ufw/new-pause-button.png delete mode 100644 third_party/golden/deborah_ufw/new-play-button.png delete mode 100644 third_party/golden/deborah_ufw/new-send-circle.png delete mode 100644 third_party/golden/deborah_ufw/numeric_25.png delete mode 100644 third_party/golden/flutter_logo.png delete mode 100644 third_party/golden/noto-emoji/emoji_u1f600.png delete mode 100644 third_party/golden/simple/blend_and_mask.png delete mode 100644 third_party/golden/simple/blend_mode_devil.png delete mode 100644 third_party/golden/simple/clip_path.png delete mode 100644 third_party/golden/simple/clip_path_2.png delete mode 100644 third_party/golden/simple/clip_path_3.png delete mode 100644 third_party/golden/simple/clip_path_transform.png delete mode 100644 third_party/golden/simple/dash_path.png delete mode 100644 third_party/golden/simple/dash_zero.png delete mode 100644 third_party/golden/simple/ellipse.png delete mode 100644 third_party/golden/simple/empty_defs.png delete mode 100644 third_party/golden/simple/empty_group.png delete mode 100644 third_party/golden/simple/equation.png delete mode 100644 third_party/golden/simple/fill-rule-inherit.png delete mode 100644 third_party/golden/simple/fill_inheritence_test.png delete mode 100644 third_party/golden/simple/group_composite_opacity.png delete mode 100644 third_party/golden/simple/group_fill_opacity.png delete mode 100644 third_party/golden/simple/group_in_defs.png delete mode 100644 third_party/golden/simple/group_mask.png delete mode 100644 third_party/golden/simple/group_opacity.png delete mode 100644 third_party/golden/simple/group_opacity_transform.png delete mode 100644 third_party/golden/simple/hidden.png delete mode 100644 third_party/golden/simple/href-fill.png delete mode 100644 third_party/golden/simple/image.png delete mode 100644 third_party/golden/simple/image_def.png delete mode 100644 third_party/golden/simple/image_transform_before_translate.png delete mode 100644 third_party/golden/simple/implicit_fill_with_opacity.png delete mode 100644 third_party/golden/simple/invalid_dash_array.png delete mode 100644 third_party/golden/simple/linear_gradient.png delete mode 100644 third_party/golden/simple/linear_gradient_2.png delete mode 100644 third_party/golden/simple/linear_gradient_absolute_user_space_translate.png delete mode 100644 third_party/golden/simple/linear_gradient_percentage_bounding_translate.png delete mode 100644 third_party/golden/simple/linear_gradient_percentage_user_space_translate.png delete mode 100644 third_party/golden/simple/linear_gradient_xlink.png delete mode 100644 third_party/golden/simple/male.png delete mode 100644 third_party/golden/simple/mask.png delete mode 100644 third_party/golden/simple/mask_with_gradient.png delete mode 100644 third_party/golden/simple/mask_with_use.png delete mode 100644 third_party/golden/simple/mask_with_use2.png delete mode 100644 third_party/golden/simple/nested_group.png delete mode 100644 third_party/golden/simple/opacity_on_path.png delete mode 100644 third_party/golden/simple/radial_gradient.png delete mode 100644 third_party/golden/simple/radial_gradient_absolute_user_space_translate.png delete mode 100644 third_party/golden/simple/radial_gradient_focal.png delete mode 100644 third_party/golden/simple/radial_gradient_percentage_bounding_translate.png delete mode 100644 third_party/golden/simple/radial_gradient_percentage_user_space_translate.png delete mode 100644 third_party/golden/simple/radial_gradient_xlink.png delete mode 100644 third_party/golden/simple/radial_ref_linear_gradient.png delete mode 100644 third_party/golden/simple/rect_rrect.png delete mode 100644 third_party/golden/simple/rect_rrect_no_ry.png delete mode 100644 third_party/golden/simple/stroke_inherit_circles.png delete mode 100644 third_party/golden/simple/style_attr.png delete mode 100644 third_party/golden/simple/text.png delete mode 100644 third_party/golden/simple/text_2.png delete mode 100644 third_party/golden/simple/text_3.png delete mode 100644 third_party/golden/simple/text_4.png delete mode 100644 third_party/golden/simple/text_5.png delete mode 100644 third_party/golden/simple/text_6.png delete mode 100644 third_party/golden/simple/use_circles.png delete mode 100644 third_party/golden/simple/use_circles_def.png delete mode 100644 third_party/golden/simple/use_emc2.png delete mode 100644 third_party/golden/simple/use_fill.png delete mode 100644 third_party/golden/simple/use_fill_test.png delete mode 100644 third_party/golden/simple/use_opacity_grid.png delete mode 100644 third_party/golden/simple/width_height_viewbox.png delete mode 100644 third_party/golden/simple/zero_width_strokes.png delete mode 100644 third_party/golden/svg_currentcolor.png delete mode 100644 third_party/golden/text_transform.png delete mode 100644 third_party/golden/w3samples/aa.png delete mode 100644 third_party/golden/w3samples/alphachannel.png delete mode 100644 third_party/golden/wikimedia/Firefox_Logo_2017.png delete mode 100644 third_party/golden/wikimedia/Flag_of_the_United_States.png delete mode 100644 third_party/golden/wikimedia/Ghostscript_Tiger.png delete mode 100644 third_party/golden/wikimedia/chess_knight.png delete mode 100644 third_party/lib/avd.dart delete mode 100644 third_party/lib/parser.dart delete mode 100644 third_party/lib/src/avd/xml_parsers.dart delete mode 100644 third_party/lib/src/avd_parser.dart rename third_party/lib/src/{picture_cache.dart => cache.dart} (69%) create mode 100644 third_party/lib/src/loaders.dart delete mode 100644 third_party/lib/src/picture_provider.dart delete mode 100644 third_party/lib/src/picture_stream.dart delete mode 100644 third_party/lib/src/render_picture.dart delete mode 100644 third_party/lib/src/svg/default_theme.dart delete mode 100644 third_party/lib/src/svg/parser_state.dart delete mode 100644 third_party/lib/src/svg/parsers.dart delete mode 100644 third_party/lib/src/svg/theme.dart create mode 100644 third_party/lib/src/utilities/_compute_io.dart create mode 100644 third_party/lib/src/utilities/_compute_none.dart create mode 100644 third_party/lib/src/utilities/compute.dart delete mode 100644 third_party/lib/src/vector_drawable.dart create mode 100644 third_party/test/cache_test.dart delete mode 100644 third_party/test/colors_svg_test.dart delete mode 100644 third_party/test/default_theme_test.dart delete mode 100644 third_party/test/error_test.dart delete mode 100644 third_party/test/golden_svg_test.dart create mode 100644 third_party/test/golden_widget/circle.em_ex2.png create mode 100644 third_party/test/golden_widget/ellipse.em_ex2.png create mode 100644 third_party/test/golden_widget/line.em_ex2.png create mode 100644 third_party/test/golden_widget/rect.em_ex2.png create mode 100644 third_party/test/loaders_test.dart delete mode 100644 third_party/test/picture_cache_test.dart delete mode 100644 third_party/test/picture_provider_test.dart delete mode 100644 third_party/test/picture_stream_test.dart delete mode 100644 third_party/test/render_picture_test.dart delete mode 100644 third_party/test/svg_parsers_test.dart delete mode 100644 third_party/test/theme_test.dart delete mode 100644 third_party/test/vector_drawable_test.dart delete mode 100644 third_party/test/xml_svg_test.dart delete mode 100644 third_party/tool/gen_golden.dart diff --git a/third_party/.cirrus.yml b/third_party/.cirrus.yml deleted file mode 100644 index dc3e8bab5d3c..000000000000 --- a/third_party/.cirrus.yml +++ /dev/null @@ -1,17 +0,0 @@ -env: - CI_NAME: "CirrusCI" - CI_BUILD_NUMBER: $CIRRUS_TASK_ID - CI_BUILD_URL: "https://cirrus-ci.com/task/$CIRRUS_TASK_ID" - CI_BRANCH: $CIRRUS_BRANCH - CI_PULL_REQUEST: $CIRRUS_PR - COVERALLS_REPO_TOKEN: ENCRYPTED[61ba3fee193a9ed6116e0f61bbe26fe8c0452287e5dfd86c728e2f1f24327818d6c74c956d7b9cbf3bd6236489af0fd1] - -test_task: - container: - matrix: - - image: cirrusci/flutter:beta - - image: cirrusci/flutter:stable - pub_script: flutter pub get - analyze_script: flutter analyze . - test_script: flutter test --coverage - coveralls_script: ./.ci/coveralls.sh diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 910b111e957c..630117fccb22 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,30 @@ # CHANGES +## 2.0.0 + +- Use parsing backend from `vector_graphics_compiler`. + - Out of order defs now supported. + - Patterns supported. + - Many optimizations added. + - **REGRESSION**: Lost support for `dx` and `dy` on `text`. See + https://github.com/dnfield/vector_graphics/issues/44 if this is important to + you. +- Parse SVG data in background isolate by default. +- Use widgets/rendering strategy from `vector_graphics`. +- Much less caching. +- More tests work without special handling - most of parsing is now sync, + and the loaders know how to avoid using `compute` in tests. For SVGs that + contain images, `vg.waitForPendingDecodes` is available. + +**DEPRECATIONS** + +- The `VectorDrawable` classes have gone away. +- The `AvdPicture` and related classes/parser have gone away. +- The `PictureCache` and `PictureStream` classes have gone away. +- The `PicturePovider` class exists only for access to a no-op cache. +- Several static members on `SvgPicture` and the `svg` utility class have gone + away. + ## 1.1.6 - Fix transforms on image tags, clipPaths. diff --git a/third_party/example/.metadata b/third_party/example/.metadata index e9290cdb98f2..7ac78721d199 100644 --- a/third_party/example/.metadata +++ b/third_party/example/.metadata @@ -1,8 +1,30 @@ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled and should not be manually edited. +# This file should be version controlled. version: - revision: d194c25bef494053b0fb6c5be4b9d46f909cad3a - channel: hide_fab + revision: 1725a26e2950a3d98e2af8c98759e11a47b2f90e + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 1725a26e2950a3d98e2af8c98759e11a47b2f90e + base_revision: 1725a26e2950a3d98e2af8c98759e11a47b2f90e + - platform: macos + create_revision: 1725a26e2950a3d98e2af8c98759e11a47b2f90e + base_revision: 1725a26e2950a3d98e2af8c98759e11a47b2f90e + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/third_party/example/ios/Flutter/Flutter.podspec b/third_party/example/ios/Flutter/Flutter.podspec deleted file mode 100644 index 5ca30416bac0..000000000000 --- a/third_party/example/ios/Flutter/Flutter.podspec +++ /dev/null @@ -1,18 +0,0 @@ -# -# NOTE: This podspec is NOT to be published. It is only used as a local source! -# - -Pod::Spec.new do |s| - s.name = 'Flutter' - s.version = '1.0.0' - s.summary = 'High-performance, high-fidelity mobile apps.' - s.description = <<-DESC -Flutter provides an easy and productive way to build and deploy high-performance mobile apps for Android and iOS. - DESC - s.homepage = 'https://flutter.io' - s.license = { :type => 'MIT' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } - s.ios.deployment_target = '8.0' - s.vendored_frameworks = 'Flutter.framework' -end diff --git a/third_party/example/lib/main.dart b/third_party/example/lib/main.dart index e8cf2283caf5..26e40be51f6b 100644 --- a/third_party/example/lib/main.dart +++ b/third_party/example/lib/main.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter_svg/avd.dart'; import 'package:flutter_svg/flutter_svg.dart'; const List _assetNames = [ @@ -101,7 +100,10 @@ class _MyHomePageState extends State<_MyHomePage> { textDirection: TextDirection.ltr, child: SvgPicture.asset( iconNames[i], - color: Colors.blueGrey[(i + 1) * 100], + colorFilter: ColorFilter.mode( + Colors.blueGrey[(i + 1) * 100] ?? Colors.blueGrey, + BlendMode.srcIn, + ), matchTextDirection: true, ), ), @@ -124,7 +126,6 @@ class _MyHomePageState extends State<_MyHomePage> { xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> ''')); - _painters.add(AvdPicture.asset('assets/android_vd/battery_charging.xml')); } @override @@ -147,7 +148,7 @@ class _MyHomePageState extends State<_MyHomePage> { ), Expanded( child: GridView.extent( - shrinkWrap: true, + // shrinkWrap: true, maxCrossAxisExtent: _dimension, padding: const EdgeInsets.all(4.0), mainAxisSpacing: 4.0, diff --git a/third_party/example/lib/simple.dart b/third_party/example/lib/simple.dart index 815f8d340f9d..c93b44e3b592 100644 --- a/third_party/example/lib/simple.dart +++ b/third_party/example/lib/simple.dart @@ -2,25 +2,17 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; const String svgString = ''' - - - - - - - - - - - - - - - - - + + + + + + + + + - '''; diff --git a/third_party/example/macos/.gitignore b/third_party/example/macos/.gitignore index d2fd3772308c..746adbb6b9e1 100644 --- a/third_party/example/macos/.gitignore +++ b/third_party/example/macos/.gitignore @@ -3,4 +3,5 @@ **/Pods/ # Xcode-related +**/dgph **/xcuserdata/ diff --git a/third_party/example/macos/Runner.xcodeproj/project.pbxproj b/third_party/example/macos/Runner.xcodeproj/project.pbxproj index ef1b05f476cf..d9333e4704c4 100644 --- a/third_party/example/macos/Runner.xcodeproj/project.pbxproj +++ b/third_party/example/macos/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 51; + objectVersion = 54; objects = { /* Begin PBXAggregateTarget section */ @@ -182,8 +182,8 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 0930; - ORGANIZATIONNAME = "The Flutter Authors"; + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; TargetAttributes = { 33CC10EC2044A3C60003C045 = { CreatedOnToolsVersion = 9.2; @@ -202,7 +202,7 @@ }; }; buildConfigurationList = 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */; - compatibilityVersion = "Xcode 8.0"; + compatibilityVersion = "Xcode 9.3"; developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( @@ -235,6 +235,7 @@ /* Begin PBXShellScriptBuildPhase section */ 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -268,7 +269,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh\ntouch Flutter/ephemeral/tripwire\n"; + shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire"; }; /* End PBXShellScriptBuildPhase section */ @@ -344,7 +345,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -361,10 +362,6 @@ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -427,7 +424,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -474,7 +471,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MACOSX_DEPLOYMENT_TARGET = 10.14; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; @@ -491,10 +488,6 @@ CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -515,10 +508,6 @@ CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter/ephemeral", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/third_party/example/macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/third_party/example/macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 764c74b8df34..000000000000 --- a/third_party/example/macos/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/third_party/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/third_party/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index df12c333e68c..fb7259e17785 100644 --- a/third_party/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/third_party/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ - - - - - - - - + + - - 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ⅅ8MglG&ER{i5lN315cO?EdHNLrg? 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 z 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 Pe7HEdAEg|=c=LY&YVNkY literal 46993 zcmZ5|3p`X?`~OCwR3s6~xD(})N~M}fiXn6%NvKp3QYhuNN0*apqmfHdR7#ShNQ99j zQi+P9nwlXbmnktZ_WnO>bl&&<{m*;O=RK!cd#$zCdM@AR`#jH%+2~+BeX7b-48x|= zZLBt9*d+MZNtpCx_&asa{+CselLUV<<&ceQ5QfRjLjQDSL-t4eq}5znmIXDtfA|D+VRV$*2jxU)JopC)!37FtD<6L^&{ia zgVf1p(e;c3|HY;%uD5<-oSFkC2JRh- z&2RTL)HBG`)j5di8ys|$z_9LSm^22*uH-%MmUJs|nHKLHxy4xTmG+)JoA`BN7#6IN zK-ylvs+~KN#4NWaH~o5Wuwd@W?H@diExdcTl0!JJq9ZOA24b|-TkkeG=Q(pJw7O;i z`@q+n|@eeW7@ z&*NP+)wOyu^5oNJ=yi4~s_+N)#M|@8nfw=2#^BpML$~dJ6yu}2JNuq!)!;Uwxic(z zM@Wa-v|U{v|GX4;P+s#=_1PD7h<%8ey$kxVsS1xt&%8M}eOF98&Rx7W<)gY(fCdmo{y*FPC{My!t`i=PS1cdV7DD=3S1J?b2<5BevW7!rWJ%6Q?D9UljULd*7SxX05PP^5AklWu^y` z-m9&Oq-XNSRjd|)hZ44DK?3>G%kFHSJ8|ZXbAcRb`gH~jk}Iwkl$@lqg!vu)ihSl= zjhBh%%Hq|`Vm>T7+SYyf4bI-MgiBq4mZlZmsKv+S>p$uAOoNxPT)R6owU%t*#aV}B z5@)X8nhtaBhH=={w;Du=-S*xvcPz26EI!gt{(hf;TllHrvku`^8wMj7-9=By>n{b= zHzQ?Wn|y=;)XM#St@o%#8idxfc`!oVz@Lv_=y(t-kUC`W)c0H2TX}Lop4121;RHE(PPHKfe_e_@DoHiPbVP%JzNudGc$|EnIv`qww1F5HwF#@l(=V zyM!JQO>Rt_PTRF1hI|u^2Uo#w*rdF*LXJky0?|fhl4-M%zN_2RP#HFhSATE3&{sos zIE_?MdIn!sUH*vjs(teJ$7^7#|M_7m`T>r>qHw>TQh?yhhc8=TJk2B;KNXw3HhnQs za(Uaz2VwP;82rTy(T3FJNKA86Y7;L(K=~BW_Q=jjRh=-k_=wh-$`nY+#au+v^C4VV z)U?X(v-_#i=3bAylP1S*pM_y*DB z2fR!imng6Dk$>dl*K@AIj<~zw_f$T!-xLO8r{OkE(l?W#W<={460Y02*K#)O4xp?W zAN+isO}!*|mN7B#jUt&!KNyFOpUxv&ybM>jmkfn8z^llBslztv!!`TBEPwu;#eR3d z@_VDa)|ByvXx1V=^Up4{;M8ji3FC7gm(C7Ty-#1gs+U<{Ouc(iV67{< zam#KwvR&s=k4W<13`}DxzJ9{TUa97N-cgWkCDc+C339)EEnC@^HQK6OvKDSCvNz(S zOFAF_6omgG!+zaPC8fBO3kH8YVBx9_AoM?->pv~@$saf(Myo|e@onD`a=;kO*Utem ze=eUH&;JB2I4}?Pm@=VnE+yb$PD~sA5+)|iH3bi|s?ExIePeoAMd(Z4Z%$mCu{t;B9(sgdG~Q}0ShAwe!l8nw0tJn zJ+m?ogrgty$3=T&6+JJa!1oS3AtQQ1gJ z3gR1<=hXU>{SB-zq!okl4c+V9N;vo4{fyGeqtgBIt%TPC1P&k!pR-GZ7O8b}9=%>3 zQrV%FQdB+CcCRKK)0}v>U25rbQk(1^9Ax|WcAo5?L(H&H@%zAoT2RH$iN6boyXpsYqME}WJZI6T%OMlkWXK>R`^7AHG&31 z&MIU}igQ7$;)7AEm#dXA+!I&6ymb7n6D;F7c$tO3Ql(`ht z1sFrzIk_q5#=!#D(e~#SdWz5K;tPF*R883Yu>*@jTeOGUjQekw zM+7HlfP{y8p}jA9bLfyKC_Ti8k#;AVp@RML^9MQp-E+Ns-Y zKA!aAZV-sfm<23fy#@TZZlQVQxH%R7rD}00LxHPUF!Yg3%OX ziDe4m<4fp{7ivBS?*AlJz$~vw5m)Ei8`|+~xOSqJ$waA0+Yys$z$9iN9TIXu8 zaYacjd09uRAsU|)g|03w`F|b1Xg#K~*Mp2X^K^)r3P^juoc}-me&YhkW3#G|H<~jK zoKD?lE@jOw7>4cpKkh!8qU!bF(i~Oa8a!EGy-j46eZYbKUvF=^^nq`EtWFK}gwrsB zeu<6~?mk+;+$whP)8ud8vjqh+NofU+Nu`~|pb&CN1y_idxxf6cGbT=fBZR_hl&G)GgnW$*oDrN-zz;cKs18n+dAn95w z)Y>l6!5eYpebJGw7it~Q5m}8$7@%p&KS=VtydFj4HPJ{xqUVS_Ih}c(^4nUdwG|0% zw8Fnm{IT`8MqoL(1BNtu_#7alS@3WSUUOFT@U*`V!zrPIeCbbO=pE%|g92$EU|lw; z^;^AqMVWVf-R5^OI79TzIyYf}HX%0Y)=aYH;EKo}?=R~ZM&s&F;W>u%hFUfNafb;- z8OkmkK3k||J#3`xdLuMJAhj9oPI?Cjt}cDN7hw26n7irWS0hsy`fs&Y?Y&(QF*Nu! z!p`NggHXaBU6$P42LkqnKsPG@363DHYGXg{!|z6VMAQt??>FK1B4x4{j;iY8A+7o% z*!0qt&w+w#Ob@pQp;q)u0;v^9FlY=AK>2!qku)!%TO<^lNBr!6R8X)iXgXi^1p`T8 z6sU@Y_Fsp6E89E1*jz~Tm2kF=mjYz_q99r^v0h-l7SP6azzL%woM6!7>IFWyizrNwAqoia3nN0q343q zFztMPh0)?ugQg5Izbk{5$EGcMzt*|=S8ZFK%O&^YV@V;ZRL>f!iG?s5z{(*Xq20c^ z(hkk~PljBo%U`$q>mz!ir7chKlE-oHA2&0i@hn4O5scsI&nIWsM>sYg;Ph5IO~VpT z%c-3_{^N>4kECzk?2~Z@V|jWio&a&no;boiNxqXOpS;ph)gEDFJ6E=zPJ$>y5w`U0 z;h9_6ncIEY?#j1+IDUuixRg&(hw+QSSEmFi%_$ua$^K%(*jUynGU@FlvsyThxqMRw z7_ALpqTj~jOSu2_(@wc_Z?>X&(5jezB6w-@0X_34f&cZ=cA-t%#}>L7Q3QRx1$qyh zG>NF=Ts>)wA)fZIlk-kz%Xa;)SE(PLu(oEC8>9GUBgd$(^_(G6Y((Hi{fsV; zt*!IBWx_$5D4D&ezICAdtEU!WS3`YmC_?+o&1RDSfTbuOx<*v`G<2SP;5Q4TqFV&q zJL=90Lcm^TL7a9xck}XPMRnQ`l0%w-fi@bRI&c*VDj!W4nj=qaQd$2U?^9RTT{*qS_)Q9OL>s}2P3&da^Pf(*?> z#&2bt;Q7N2`P{{KH@>)Tf5&za?crRmQ%8xZi<9f=EV3={K zwMet=oA0-@`8F;u`8j-!8G~0TiH5yKemY+HU@Zw3``1nT>D ziK465-m?Nm^~@G@RW2xH&*C#PrvCWU)#M4jQ`I*>_^BZB_c!z5Wn9W&eCBE(oc1pw zmMr)iu74Xl5>pf&D7Ml>%uhpFGJGyj6Mx=t#`}Mt3tDZQDn~K`gp0d)P>>4{FGiP$sPK*ExVs!1)aGgAX z6eA;-9@@Muti3xYv$8U{?*NxlHxs?)(6%!Iw&&l79K86h+Z8;)m9+(zzX?cS zH*~)yk)X^H1?AfL!xctY-8T0G0Vh~kcP=8%Wg*zZxm*;eb)TEh&lGuNkqJib_}i;l z*35qQ@}I#v;EwCGM2phE1{=^T4gT63m`;UEf5x2Get-WSWmt6%T6NJM`|tk-~4<#HHwCXuduB4+vW!BywlH8murH@|32CNxx7} zAoF?Gu02vpSl|q1IFO0tNEvKwyH5V^3ZtEO(su1sIYOr{t@Tr-Ot@&N*enq;Je38} zOY+C1bZ?P~1=Qb%oStI-HcO#|WHrpgIDR0GY|t)QhhTg*pMA|%C~>;R4t_~H1J3!i zyvQeDi&|930wZlA$`Wa9)m(cB!lPKD>+Ag$5v-}9%87`|7mxoNbq7r^U!%%ctxiNS zM6pV6?m~jCQEKtF3vLnpag``|bx+eJ8h=(8b;R+8rzueQvXgFhAW*9y$!DgSJgJj% zWIm~}9(R6LdlXEg{Y3g_i7dP^98=-3qa z$*j&xC_$5btF!80{D&2*mp(`rNLAM$JhkB@3al3s=1k^Ud6HHontlcZw&y?`uPT#a za8$RD%e8!ph8Ow7kqI@_vd7lgRhkMvpzp@4XJ`9dA@+Xk1wYf`0Dk!hIrBxhnRR(_ z%jd(~x^oqA>r>`~!TEyhSyrwNA(i}={W+feUD^8XtX^7^Z#c7att{ot#q6B;;t~oq zct7WAa?UK0rj0yhRuY$7RPVoO29JV$o1Z|sJzG5<%;7pCu%L-deUon-X_wAtzY@_d z6S}&5xXBtsf8TZ13chR&vOMYs0F1?SJcvPn>SFe#+P3r=6=VIqcCU7<6-vxR*BZUm zO^DkE{(r8!e56)2U;+8jH4tuD2c(ptk0R{@wWK?%Wz?fJckr9vpIU27^UN*Q$}VyHWx)reWgmEls}t+2#Zm z_I5?+htcQl)}OTqF<`wht89>W*2f6e)-ewk^XU5!sW2A2VtaI=lggR&I z;Rw{xd)WMqw`VUPbhrx!!1Eg_*O0Si6t@ny)~X^Gu8wZZDockr)5)6tm+<=z+rYu? zCof+;!nq6r9MAfh zp4|^2w^-3vFK~{JFX|F5BIWecBJkkEuE%iP8AZ z^&e|C+VEH&i(4Y|oWPCa#C3T$129o5xaJa=y8f(!k&q+x=M|rq{?Zw_n?1X-bt&bP zD{*>Io`F4(i+5eE2oEo6iF}jNAZ52VN&Cp>LD{MyB=mCeiwP+v#gRvr%W)}?JBTMY z_hc2r8*SksC%(pp$KGmWSa|fx;r^9c;~Q(Jqw1%;$#azZf}#Fca9NZOh{*YxV9(1ivVA^2Wz>!A&Xvmm-~{y8n!^Jdl8c>`J#=2~!P{ zC1g_5Ye3={{fB`R%Q|%9<1p1;XmPo5lH5PHvX$bCIYzQhGqj7hZ?@P4M0^mkejD|H zVzARm7LRy|8`jSG^GpxRIs=aD>Y{Cb>^IwGEKCMd5LAoI;b{Q<-G}x*e>86R8dNAV z<@jb1q%@QQanW1S72kOQ$9_E#O?o}l{mHd=%Dl{WQcPio$baXZN!j{2m)TH1hfAp{ zM`EQ=4J`fMj4c&T+xKT!I0CfT^UpcgJK22vC962ulgV7FrUrII5!rx1;{@FMg(dIf zAC}stNqooiVol%%TegMuWnOkWKKA}hg6c)ssp~EnTUVUI98;a}_8UeTgT|<%G3J=n zKL;GzAhIQ_@$rDqqc1PljwpfUwiB)w!#cLAkgR_af;>}(BhnC9N zqL|q8-?jsO&Srv54TxVuJ=rfcX=C7{JNV zSmW@s0;$(#!hNuU0|YyXLs{9$_y2^fRmM&g#toh}!K8P}tlJvYyrs6yjTtHU>TB0} zNy9~t5F47ocE_+%V1(D!mKNBQc{bnrAbfPC2KO?qdnCv8DJzEBeDbW}gd!g2pyRyK`H6TVU^~K# z488@^*&{foHKthLu?AF6l-wEE&g1CTKV|hN7nP+KJnkd0sagHm&k{^SE-woW9^fYD z7y?g*jh+ELt;$OgP>Se3o#~w9qS}!%#vBvB?|I-;GM63oYrJ}HFRW6D+{54v@PN8K z2kG8`!VVc+DHl^8y#cevo4VCnTaPTzCB%*)sr&+=p{Hh#(MwaJbeuvvd!5fd67J_W za`oKxTR=mtM7P}i2qHG8=A(39l)_rHHKduDVA@^_Ueb7bq1A5#zHAi**|^H@fD`_W z#URdSG86hhQ#&S-Vf_8b`TIAmM55XhaHX7}Ci-^(ZDs*yb-WrWV&(oAQu3vMv%u$5 zc;!ADkeNBN_@47r!;%G3iFzo;?k)xTS-;1D-YeS5QXN7`p2PzGK~e6ib;8COBa5)p zfMn}dA--&A12~zr&GVk?qnBGfIEo`5yir;-Q;ZLn{Fimdrk;e!)q`sAkYh^~^>4Q@ zN5RT>s38+`V{|6@k&vZW!W0*BEqV&~34d+Ev8h)ObYL7Bd_hgbUzjdJaXP=S@Dp6X z)i013q3K4Gr5d%2YIp>218pYK!xwH;k)j?uUrT-yVKLg*L3y~=a+qd!RWGTL`z>29 z-Zb4Y{%pT%`R-iA#?T58c-i@?jf-Ckol9O>HAZPUxN%Z=<4ad9BL7n`_kH0i#E(m& zaNb039+z~ONUCLsf_a|x*&ptU?`=R*n}rm-tOdCDrS!@>>xBg)B3Sy8?x^e=U=i8< zy7H-^BPfM}$hf*d_`Qhk_V$dRYZw<)_mbC~gPPxf0$EeXhl-!(ZH3rkDnf`Nrf4$+ zh?jsRS+?Zc9Cx7Vzg?q53ffpp43po22^8i1Obih&$oBufMR;cT2bHlSZ#fDMZZr~u zXIfM5SRjBj4N1}#0Ez|lHjSPQoL&QiT4mZn=SxHJg~R`ZjP!+hJ?&~tf$N!spvKPi zfY;x~laI9X`&#i#Z}RJ`0+MO_j^3#3TQJu2r;A-maLD8xfI+2Y*iDf4LsQ$9xiu?~ z?^wHEf^qlgtjdj(u_(W5sbGx1;maVPDHvI-76u2uUywf;>()=e>0le;bO0LIvs)iy z*lJTO+7gyf^)2uS-PhS_O-+RToQmc6VT>ej^y^stNkwIxUg?E|YMAAwQ}U!dC&cXL ziXKU?zT~xbh6C};rICGbdX~;8Z%L~Jdg|`senVEJo-CiDsX47Kc`;EiXWO<9o)(`4 zGj(9@c+Me=F~y(HUehcAy!tkoM&e1y#(qqCkE(0lik_U>wg8vOhGR(=gBGFSbR`mh zn-%j3VTD4 zwA1Kqw!OSgi_v0;6?=Bk4Z{l-7Fl4`ZT535OC{73{rBwpNHMPH>((4G`sh zZhr!v{zM@4Q$5?8)Jm;v$A2v$Yp9qFG7y`9j7O-zhzC+7wr3Cb8sS$O{yOFOODdL) zV2pU{=nHne51{?^kh%a$WEro~o(rKQmM!p?#>5Pt`;!{0$2jkmVzsl|Nr^UF^IHxG z8?HmZEVMY~ec%Ow6hjfg6!9hCC4xY?V;5Ipo-myV=3TmfT^@XkKME`+=_inm4h7ki z->K~a+20?)zic^zc&7h=0)T{Aa24FU_}(O|9DMW3Bf>MW=O%~8{unFxp4}B+>>_KN zU%rKs3Va&&27&OX4-o&y2ie|sN2p-=S^V<2wa2NUQ4)?0e|hgna*1R7(#R_ys3xmG zE#(ry+q=O~&t|RX@ZMD`-)0QmE*x%SBc(Yvq60JtCQ4RL(gdA(@=}0rYo5yKz36bW zkvLOosP6I?7qH!rce(}q@cH-{oM2ThKV2RZe+{{25hkc?T>=Tky12xHr0jmfH@SZi zLHPJ@^Oo^Zo%`gZk_hrbCzS+t|=O!Bt zWi|>M8mz~sD|Z>C1ZPf_Cs&R!S5E2qK+@j*UpP>;5_|+h+y{gb=zub7#QKSUabet# zFH2H0ul;zO+uc+V=W_W@_Ig-791T7J9&=5)wrBE?JEHS_A6P~VQ)u6s1)Pu|VxP(aYJV*(e<)(42R zm3AK>dr1QLbC1RMoQ|M5k+TWBjY9q+_vY=K-tUte35m4RWl51A<4O0ptqV3)KzL7U z0gpp-I1)|zvtA8V7-e-o9H)lB_Rx6;Bu7A2yE)6)SuDqWDs}~Ojfk?DFwI% z3E1(>LbbB7I(&E@B7nlulhvY=Wa1mGXD@ijD7WF^y@L1e55h)-hzoq}eWe!fh9m3V{)x^6F8?ed1z>+4;qW6A4hYYj zZCYP=c#I8+$pAIVyiY*#%!j3ySAnH`tp|=^lh{)#JimWaP_rXK40A0WcsEUj`G1}O zG?XQ~qK4F!lqauv6-BL_Up3+-l1=kVfD;D*C)yr>o9>W=%mIyATtn_OBLK+h@p)j5jRAb;m&Ok?TZH-5Q)~#UwdYFp~rEE{judWa9E)z zE>135C-xMdHYY&AZGR)tb`K}s0CK9 z1!))p^ZaUC*e50t`sL+)@`)#kJ}?C_cCMH@k{f4wh~0`OFnGQ2nzUuuu;=r4BYRcI z){G#a6Y$S(mIc6B#YS;jFcU{0`c)Raa$nG+hV(K|2|^ZWOI566zlF0N;t~$jD<_AX zjnD?HN-G>xRmHwtL3BcJX7)Q^YGfc?cS4Nj=yYl5MB(uBD?r@VTB|mIYs=au$e)e{ zLHWd!+EN*v2*(=y%G1JzyQdY&%|?~R5NPb)`S2dw1AJW8O;L=p?yVxJs=X?U#-l1O zk6xh8yyY;OTR7aF{P=kQ>y`*EFivnw%rQioA-I67WS+~hVamG4_sI)(Jo4vHS|@F@ zqrBHbxHd_Y8+?8Gfq=Z1O^Fs5moGayCHVUHY^8)^j)Aj*RB!S2-FA?4#-`puwBW`` zJ_6OQj(FGo8DotHYRKq;;$4xDn9=4rgw}5xvxhi)?n?W5{*%4%h9Tg)zlQl&fN~Z1)gL(Dn7X!P428I zwA+U-x5!cQ57g1N=2bLqAWF z!&cbvsD)dvYoqP5vaQz%rL@kv*J>0AMzWAKn~Mxi5g2GlI7qvVZo)Z5oj=#O!M&*O z`3O3)uvrjNTeremC}nW@(m%#E-sITB>j-!yBM#(=FN`~c#@XjL3e)SjR9&%QO%tUg zzGv=SLH()`ZIt?Ayym;9VG1Muq+a+7Zo+59?SuRu_`k>@S4!yS3roMnq+SDO?`C7V#2 z8vHf4&0k;{kLT)fa==7EILSu3e|ZnxtFO;1 zGqP-;Xo(>_QKcYUhsi-X72BqH#7Zb-TsiNIF>G9xOHT3XoA*qX^10+#XCU0)UO4_%A_s_vO=uDd3_Q%D{OsvLMW9wGvuuRnF52{2vH06D~7N672!bIMt@it_D}& zwjZ7gV!RzZ86*wbEB5cnMJRbEqMM{G!K)bfJjyPH^9nGnrOI9S{~!dm4~P#&b*~)h zCMwM8mR+y5i~E5*JAopwZ>F`=ORfA&IF%O8(aS<}^H6wcY1g^=lYLPtFpyvW9F z3;FCS-TGFYPr#Y$ue>}?rTYrmWr^VbUu>!eL$cEdh1e>5_UDnZ@Mu$l*KVo_NDEu^ zBn*!qVnzYv>t|<(>nt8%CoNPhN!qGP|sANRN^#+2YSSYHa>R1mss->c0f=#g@U58@? zA4sUbrA7)&KrTddS0M6pTSRaz)wqUgsT3&8-0eG|d;ULOUztdaiD3~>!10H`rRHWY z1iNu6=UaA8LUBoaH9G*;m`Mzm6d1d+A#I8sdkl*zfvbmV0}+u` zDMv=HJJm?IOwbP;f~yn|AI_J7`~+5&bPq6Iv?ILo2kk$%vIlGsI0%nf1z9Mth8cy! zWumMn=RL1O9^~bVEFJ}QVvss?tHIwci#ldC`~&KFS~DU5K5zzneq_Q91T~%-SVU4S zJ6nVI5jeqfh~*2{AY#b(R*Ny95RQBGIp^fxDK{I9nG0uHCqc-Ib;pUUh$t0-4wX*< z=RzW~;iR3xfRnW<>5Jr5O1MP)brA3+ei@H8Hjkt7yuYIpd7c-4j%U=8vn8HD#TPJo zSe+7~Db}4U3Y^4dl1)4XuKZ67f(ZP;?TYg9te>hbAr4R_0K$oq3y5m-gb?fR$UtF9 zS~S^=aDyFSE}9W2;Okj%uoG-Um^&Qo^bB#!W?|%=6+P>``bumeA2E7ti7Aj%Fr~qm z2gbOY{WTyX$!s5_0jPGPQQ0#&zQ0Zj0=_74X8|(#FMzl`&9G_zX*j$NMf?i3M;FCU z6EUr4vnUOnZd`*)Uw#6yI!hSIXr%OF5H z5QlF8$-|yjc^Y89Qfl!Er_H$@khM6&N*VKjIZ15?&DB?);muI`r;7r0{mI03v9#31 z#4O*vNqb=1b}TjLY`&ww@u^SE{4ZiO=jOP3!|6cKUV2*@kI9Aw0ASwn-OAV~0843$1_FGl7}eF6C57dJb3grW)*jtoUd zpqXvfJSCIv4G*_@XZE?> z4Lt=jTSc*hG3`qVq!PVMR2~G-1P{%amYoIg!8Odf4~nv6wnEVrBt-R5Au=g~4=X|n zHRJGVd|$>4@y#w;g!wz>+z%x?XM^xY%iw%QoqY@`vSqg0c>n_}g^lrV))+9n$zGOP zs%d&JWT2Jjxaz`_V%XtANP$#kLLlW=OG2?!Q%#ThY#Sj}*XzMsYis2HiU2OlfeC>d z8n8j-{Npr1ri$Jv2E_QqKsbc$6vedBiugD~S`_0QjTTtX(mS}j6)6e;xdh*sp5U0aMpuN}qTP=^_Qn zh~0padPWs&aXmf6b~}{7Raglc)$~p?G89N4)&a}`izf|bA)IUmFLQ8UM$T!6siQxr z=%)pPsWYXWCNdGMS3fK6cxVuhp7>mug|>DVtxGd~O8v@NFz<+l`8^#e^KS3})bovWb^ zILp4a_9#%Y*b6m$VH8#)2NL@6a9|q!@#XOXyU-oAe)RR$Auj6?p2LEp*lD!KP{%(- z@5}`S$R)Kxf@m68b}Tr7eUTO=dh2wBjlx;PuO~gbbS2~9KK1szxbz$R|Frl8NqGn= z2RDp@$u5Obk&sxp!<;h=C=ZKPZB+jk zBxrCc_gxabNnh6Gl;RR6>Yt8c$vkv>_o@KDMFW1bM-3krWm|>RG>U`VedjCz2lAB1 zg(qb_C@Z~^cR=_BmGB@f;-Is3Z=*>wR2?r({x}qymVe?YnczkKG%k?McZ2v3OVpT* z(O$vnv}*Tle9WVK_@X@%tR^Z!3?FT_3s@jb3KBVf#)4!p~AFGgmn%1fBbZe3T53$_+UX_A!@Kz63qSLeH@8(augJDJ;RA>6rNxQYkd6t(sqK=*zv4j;O#N(%*2cdD z3FjN6`owjbF%UFbCO=haP<;Y1KozVgUy(nnnoV7{_l5OYK>DKEgy%~)Rjb0meL49X z7Fg;d!~;Wh63AcY--x{1XWn^J%DQMg*;dLKxs$;db`_0so$qO!>~yPDNd-CrdN!ea zMgHt24mD%(w>*7*z-@bNFaTJlz;N0SU4@J(zDH*@!0V00y{QfFTt>Vx7y5o2Mv9*( z1J#J27gHPEI3{!^cbKr^;T8 z{knt%bS@nrExJq1{mz2x~tc$Dm+yw=~vZD|A3q>d534za^{X9e7qF29H5yu};J)vlJkKq}< zXObu*@ioXGp!F=WVG3eUtfIA$GGgv0N?d&3C47`Zo)ms*qO}A9BAEke!nh#AfQ0d_ z&_N)E>5BsoR0rPqZb)YN}b~6Ppjyev;MMis-HkWF!az%G? z#&it84hv!%_Q>bnwch!nZKxB05M=jgiFaB^M=e-sj1xR?dPYUzZ#jua`ggyCAcWY> z-L$r#a{=;JP5X}9(ZPC&PdG~h5>_8SueX($_)Qu(;()N3*ZQH(VGnkWq^C}0r)~G3_?a10y*LsFz zokU5AKsW9DUr-ylK61shLS#4@vPcteK-Ga9xvRnPq=xSD_zC=Q_%6IuM?GpL(9aDx z|8d_;^6_D4{IQ1ndMAcFz5ZaT+Ww0wWN`xP(U#^=POs(BpKm;(H(lmYp+XCb7Kaw0 z;LT945Ev3IkhP6$lQBiMgr+vAL}{8xO&IObqJBEP4Y^x&V?iGC=1lVIbH^Z!eXxr@ zz)D7Fon`z~N|Pq>Bsue&_T9d;G+d8#@k^cq~F^I8ETsZ*cGOf*gZ4ghlAzW|aZ;WA13^B!Tlr0sWA zosgXD-%zvO-*GLU@hVV(bbQ`s@f~Ux=4}(@7O)%o5EH((gYflccBC@jbLF3IgPozv zglX2IL}kL1rtn4mu~`J(MMY83Rz6gc1}cX4RB+tZO2~;3FI# z@dU(xa5J_KvL0)oSkvwz9|!QcEA$jKR@a-4^SU3O449TrO+x$1fkBU<<=E_IHnF6> zPmZ7I2E+9A_>j6og$>Nih~b2F_^@6ef|Hm-K2(>`6ag{Vpd`g35n`yW|Jme78-cSy z2Jz7V#5=~u#0eLSh3U4uM3Smk31>xEh^-Os%&5tK6hSAX83jJi%5l!MmL4E?=FerNG#3lj^;-F1VISY!4E)__J~gY zP{o~Xo!8DW{5lsBFKL~OJiQoH>yBZ+b^};UL&UUs!Hbu7Gsf<9sLAsOPD4?-3CP{Q zIDu8jLk6(U3VQPyTP{Esf)1-trW5Mi#zfpgoc-!H>F$J#8uDRwDwOaohB(_I%SuHg zGP)11((V9rRAG>80NrW}d`=G(Kh>nzPa1M?sP;UNfGQaOMG1@_D0EMIWhIn#$u2_$ zlG-ED(PU+v<1Dd?q-O#bsA)LwrwL>q#_&75H)_X4sJK{n%SGvVsWH7@1QZqq|LM`l zDhX8m%Pe5`p1qR{^wuQ&>A+{{KWhXs<4RD< z=qU6)+btESL>kZWH8w}Q%=>NJTj=b%SKV3q%jSW>r*Qv1j$bX>}sQ%KO7Il zm?7>4%Q6Nk!2^z})Kchu%6lv-7i=rS26q7)-02q?2$yNt7Y={z<^<+wy6ja-_X6P4 zoqZ1PW#`qSqD4qH&UR57+z0-hm1lRO2-*(xN-42|%wl2i^h8I{d8lS+b=v9_>2C2> zz(-(%#s*fpe18pFi+EIHHeQvxJT*^HFj2QyP0cHJw?Kg+hC?21K&4>=jmwcu-dOqEs{%c+yaQ z2z6rB>nPdwuUR*j{BvM-)_XMd^S1U|6kOQ$rR`lHO3z~*QZ71(y(42g`csRZ1M@K7 zGeZ27hWA%v`&zQExDnc@cm9?ZO?$?0mWaO7E(Js|3_MAlXFB$^4#Zpo;x~xOEbay( zq=N;ZD9RVV7`dZNzz+p@YqH@dW*ij8g053Cbd=Mo!Ad8*L<5m1c4Kk ziuca5CyQ05z7gOMecqu!vU=y93p+$+;m=;s-(45taf_P(2%vER<8q3}actBuhfk)( zf7nccmO{8zL?N5oynmJM4T?8E))e;;+HfHZHr` zdK}~!JG}R#5Bk%M5FlTSPv}Eb9qs1r0ZH{tSk@I{KB|$|16@&`0h3m7S+)$k*3QbQ zasW2`9>hwc)dVNgx46{Io zZ}aJHHNf1?!K|P;>g7(>TefcLJk%!vM`gH8V3!b= z>YS+)1nw9U(G&;7;PV4eIl{=6DT^Vw<2Elnox;u@xF5ad*9Fo|yKgq<>*?C$jaG2j z|29>K)fI^U!v?55+kQ*d2#3}*libC4>Dl4 zIo3Jvsk?)edMnpH<|*l<*0Pf{2#KedIt>~-QiB{4+KEpSjUAYOhGDpn3H_N9$lxaP ztZwagSRY~x@81bqe^3fb;|_A7{FmMBvwHN*Xu006qKo{1i!RbN__2q!Q*A;U*g-Mz zg)-3FZ`VJdognZ~WrWW^2J$ArQAr1&jl~kWhn+osG5wAlE5W&V%GI{8iMQ!5lmV~# zeb3SKZ@?7p;?7{uviY6`Oz16t0=B70`im=`D@xJa16j2eHoCtElU*~7={YUzN41sE z#Th>DvJq-#UwEpJGKx;;wfDhShgO0cM|e!Ej){RX#~>a?)c2|7Hjhh2d=)VUVJL<^Aq|>_df4DX>b9W2$_DM zTjF#j(9?Co`yor?pK<16@{h#F&F8~1PG|qQNZPX^b!L*L&?PH#W8za0c~v6I2W($Jderl%4gufl z#s;C*7APQJP46xHqw;mUyKp3}W^hjJ-Dj>h%`^XS7WAab^C^aRu1?*vh-k2df&y9E z=0p*sn0<83UL4w30FqnZ0EvXCBIMVSY9Zf?H1%IrwQybOvn~4*NKYubcyVkBZ4F$z zkqcP*S>k6!_MiTKIdGlG+pfw>o{ni`;Z7pup#g z4tDx3Kl$)-msHd1r(YpVz7`VW=fx9{ zP}U8rJ-IP)m}~5t&0Y$~Quyjflm!-eXC?_LMGCkZtNDZf0?w<{f^zp&@U@sQxcPOZ zBbfQTFDWL_>HytC*QQG_=K7ZRbL!`q{m8IjE0cz(t`V0Ee}v!C74^!Fy~-~?@}rdn zABORRmgOLz8{r!anhFgghZc>0l7EpqWKU|tG$`VM=141@!EQ$=@Zmjc zTs`)!A&yNGY6WfKa?)h>zHn!)=Jd73@T^(m_j|Z;f?avJ{EOr~O~Q2gox6dkyY@%M zBU+#=T?P8tvGG|D5JTR}XXwjgbH(uwnW%W?9<-OQU9|6H{09v#+jmnxwaQ-V;q{v% zA8srmJX7Fn@7mr*ZQ@)haPjWVN@e3K z_`+@X$k*ocx*uF^_mTqJpwpuhBX~CSu=zPE(Sy%fYz&lzZmz3xo4~-xBBvU0Ao?;I-81*Z%8Do+*}pqg>bt^{w-`V6Sj>{Znj+ z70GS2evXinf|S#9=NNoXoS;$BTW*G0!xuTSZUY45yPE+~*&a-XC+3_YPqhd*&aQ>f z$oMUq^jjA;x#?iJKrpAqa<2<21h*_lx9a}VMib;a6c$~=PJOj6XJXJ|+rc7O7PEN5uE7!4n9nllo@BI4$VW2Nf_jqnkz%cvU4O4umV z#n6oXGWOt3tuIjmX*b!!$t~94@a@QgybLpQo3icAyU`iNbY~XNAArFAn$nFJ()d-U zFaO#nxxVF-%J{UB**uRo0*+?S>=^il)1m7v-u`PDy*ln%|3E-{3U~R=QcE&zhiG_c zDnGMgf1}3h1gWz8IV0Oc7FmEt>6W?Eva;J`(!;IIny}PvD?vztz`F6su_tUO`M%K5 z%C#=nXbX})#uE!zcq2mB;hPUVU1!`9^2K303XfOIVS{mlnMqJyt}FV=$&fgoquO+N zU6!gWoL%3N1kyrhd^3!u>?l6|cIl*t4$Z$=ihyzD7FFY~U~{RaZmfyO4+$kC7+m zo+-*f-VwpUjTi_Idyl~efx)!$GpE!h+in4G1WQkoUr<#2BtxLNn*2A>a-2BL#z%QO@w0v^{s=`*I6=ew2nUj1=mvi%^U@2#Wf& zs1@q6l8WqrqGm!)Yr|*``||#A+4#du6`mR^_#?CymIr}O!8Zm?(XY$u-RGH;?HFMGIEYVuA1& z`3RlG_y0%Mo5w@-_W$E&#>g6j5|y1)2$hg(6k<{&NsACgQQ0c8&8Tdth-{@srKE*I zAW64%AvJJ+Z-|I~8`+eWv&+k8vhdJk5%jolc%e`^%_vul0~U8t)>=bU&^ z6qXW&GDP%~1{L1-nKK>IsFgDJrh>!wr3?Vu-cmi#wn`;F`$GNc_>D|>RSuC8Vh21N z|G;J1%1YxwLZDD400Ggw+FirsoXVWYtOwg-srm}6woBb!8@OIc`P$!?kH>E55zbMB z8rdpODYfVmf>cF`1;>9N>Fl(Rov!pm=okW>I(GNJoNZ6jfIunKna-h6zXZPoZ9E2PythpyYk3HRN%xhq2c?gT$?4}Ybl42kip$QiA+ab zf-!EqBXkT1OLW>C4;|irG4sMfh;hYVSD_t6!MISn-IW)w#8kgY0cI>A`yl?j@x)hc z=wMU^=%71lcELG|Q-og8R{RC9cZ%6f7a#815zaPmyWPN*LS3co#vcvJ%G+>a3sYE`9Xc&ucfU0bB}c_3*W#V7btcG|iC>LctSZUfMOK zlIUt>NBmx6Ed}w_WQARG+9fLiRjS1;g49srN1Xi&DRd|r+zz*OPLWOu>M?V>@!i49 zPLZ3Q(99%(t|l%5=+9=t$slX0Pq(K@S`^n|MKTZL_Sj+DUZY?GU8sG=*6xu)k5V3v zd-flrufs*;j-rU9;qM zyJMlz(uBh0IkV<(HkUxJ747~|gDR6xFu?QvXn`Kr|IWY-Y!UsDCEqsE#Jp*RQpnc# z8y3RX%c2lY9D*aL!VS`xgQ^u0rvl#61yjg03CBER7-#t7Z++5h_4pw{ZZ~j0n_S_g zR=eVrlZDiH4y2}EZMq2(0#uU|XHnU!+}(H*l~J&)BUDN~&$ju@&a=s$tH5L`_wLeB z944k;)JIH^T9GEFlXiNJ6JRymqtLGZc?#Mqk2XIWMuGIt#z#*kJtnk+uS;Gp}zp$(O%LOC|U4ibw%ce-6>id$j5^y?wv zp1At~Sp7Fp_z24oIbOREU!Mji-M;a|15$#ZnBpa^h+HS&4TCU-ul0{^n1aPzkSi1i zuGcMSC@(3Ac6tdQ&TkMI|5n7(6P4(qUTCr)vt5F&iIj9_%tlb|fQ{DyVu!X(gn<3c zCN6?RwFjgCJ2EfV&6mjcfgKQ^rpUedLTsEu8z7=q;WsYb>)E}8qeLhxjhj9K**-Ti z9Z2A=gg+}6%r9HXF!Z~du|jPz&{zgWHpcE+j@p0WhyHpkA6`@q{wXl6g6rL5Z|j~G zbBS~X7QXr3Pq0$@mUH1Snk^1WJ0Fx2nTyCGkWKok$bJZV0*W?kjT|mkUpK<)_!_K^OoTjMc+CWc^~{ZP8vgm`f&=ppzKtw}cxwV^gppu}^df1|va7Q?@=(076-( z4KJVmu?l(aQwmQ*y_mke>YLW^^Rsj@diLY$uUBHL3yGMwNwb7OR3VD%%4tDW(nC984jBWCd90yY(GEdE8s(j>(uPfknLwh!i6*LX}@vvrRCG`c?EdB8uYU zqgsI4=akCeC+&iMNpVu56Fj2xZQHs6SdWssIF#Q@u@f9kab0&y*PlG+PynjHy`}GT zg%aTjRs2+7CknhTQKI%YZhFq1quSM{u24Oy2As@4g(bpbi%y1i0^TwI)%1Whpa~qE zX4MD(PgFEK@jZBPXkFd437aL6#COs$WrNT#U=er-X1FX{{v9!0AS$HR{!_u;zldwY zKko!`w2u@($c&k_3uLFE0Z*2vms?uw1A{AqZw^jwg$|D7jAY20j`s*l##=4Ne_K5) zOtu6_kziEF@vPsS7+@UwqOW6>OUwF$j{r4=nOSf-{UC(rEKidie7IUn>5`UoNJ9k) zxJXXEBQifng+Pte3mPQ76pVlZ<`jnI##F1*YFA*)ZCEncvgF-%)0dUXV*pXTT^L`n zL=?A5Vty#{R9W4K)m$`me~*_(&a88M?Eon$P-YdVG}#Gq4=hh#w=`>8f`9}}zhv;~ za?I=Gb3v$Ln?-SDTBow0J5Tt&xPlw|%`*VTyVee1Oh<-&;mA|;$ zoPl;^f7Q~}km#_#HT2|!;LEqORn%~KJaM)r#x_{PstSGOiZ!zX2c}^!ea3+HSWrwE z=6SJ!7sNDPdbVr#vnUf}hr&g@7_Yj&=sY=q(v^BwLKQm|oSB}172GpPlj?a3GqX#B zJko4zRRttIY>Fv#2b#A<_DLx=T@eUj+f}!u?p)hmN)u4(Jp(`9j58ze{&~rV?WVbP z%A=|J96mQjtD037%>=yk3lkF5EOIYwcE;uQ5J6wRfI^P3{9U$(b>BlcJF$2O;>-{+a1l4;FSlb z_LRpoy$L%S<&ATf#SE z;L?-lQlUDX_s&jz;Q1Lr@5>p_RPPReGnBNxgpD!5R#3)#thAI3ufgc^L)u%Rr+Hlb zT(pLDt%wP7<%z(utq=l%1M78jveI@T$dF#su(&>JkE(#=f4;D54l*%(-^(nfbCUQe)FV9non9F%K+KZ(4_`uOciy82CO)OolxisUd0m^cqueIRnY< z;BgA4S1&XC3uUP?U$}4o&r|0VCC7fkuMZBa|2n4asR>*5`zBaOJPWT$bNn(W_CK%L$c2AsfSlwq?A8Q6 zhK&USSV=^-4vZ^5<}pnAOb&IKseHNxv_!|B{g@d^&w%{?x;i3iSo)+vt^VnMmS!v) zM)W)05vXqzH5^hOWWw~$#&7HoIw}}DD3bCQgc=I8Rv|G5fM8O^58?--_-*>%Nwk)j zIfvfok0n05!w%tZ=-dpffezI7(+}yX5XhwYk#0@KW%PkR;%#t|P6Ze_K*N6ns%jOt zNeW(bRsv0BK7ah~9U~UBAVA_L34F+;14x6-;I|o=%>?sS3@dpRv|GKxilsa#7N#@! z!RX~>&JX&r{A^^>S~n_hPKkPR_(~~g>SuPj5Kx6VI%8BOa(Iit&xSMU8B#EY-Wr?9 zOaRPw0PEbVSW@Wk{8kkVn34;D1pV2mUXnXWp{V-M9+d}|qfb6F`!a9JQO_-wlH?zf z4Sn0F4-q-tzkaJ?1fV0+cJBF$f0g6*DL6U3y`Tr`1wzCiwY#muw7Q-Ki)uN}{MoCWP%tQ@~J4}tyr1^_bV9PScNKQHK=BZFV!`0gRe?mVxhcA4hW5?p0B<5oK+?vG^NM%B%NDOvu0FMq#)u&zt_-g&2 z7?z%~p&32OAUSQV{<=pc_j2^<;)`8$zxCEomh=rvMiliShS?ahdYI1grE-M&+qkK_ zD=5Hexi<&8qb4hgtgj81OD(tfX3EJSqy9KFcxpeBerG`apI4!#93xpEFT??vLt>kf zac28;86CpMu=BWIe$NOT~+Es!y#+$ zvm2s*c`J9Gy*ERvLSI<9<=j*O=0xUG>7rYh^R4bGsvz;j-SBO|P^OQ1>G9_akF}D; zlRmB@k3c5!s|Vz3OMZ8M*n0AMTiSt5ZpRy+R1|ckna&w`UQjklt9f&0Z~=->XImVA zLXizO2h=<|wM~w>%}3q1!E{oSq7LBPwQ~93p-peDq-W?wCm8NOKgTSz-P)|cm}S5&HBsx#C@Ba5;hzi#Yw@y-kC~)@u4}Rf?KV0$lPjv}} zcFpNy=YJfsS||9&!-JFjw=@NU96ESzU^gme0_oNy?})II`>Sy>bUCHs_(m&)vn^&isCl+`F~qu8elAO z)-ZP7`gYE2H(1)5tKalz&NJbcutAU&&JFV~$Jrai31^j>vZ|HV1f}#C1<5>F8 zS1RWIzM%b{@2dAF^$+i4p>TC8-weiLAPN+Aa#(bxXo9%Vz2NEkgF&s#_>V?YPye^_ z`` z-h3Cv^m6K%28I$e2i=cFdhZN?JTWhqJC{Q9mg0Vg|FiPEWDl&K)_;Bz_K`jH7W7QX^d$WQF*iF@#4_P*D36w9&iJr2E{w?LRFapwZIIVHGH ziTp*5>T{=;(E}z{1VL4;_H`BAXA~&zpeWX!gN9m|AfcJ{`!XVz48O^&+0Gd|w;udP zzU|DbGTS|7qZoEoDZEH9Kb0%DZvCaWDzuJ=8jZz}pqPn+I!c_+*~>m>BQqN2560*< z$6sx_y8WRqj$SugYGip+et$;iJ!SQAx=HgVSh_3e)MOFHuXD@sg>Yi_p8Sh`{lP=5 zo?AFv1h;KqR`Yj!8Pjji3lr+qae2|a1GmlxE*su%_V)K0Xu0(#2LcO!*k11w*V12$ z;f~i{kI#9PzvFLZ3pz@d558HeK2BTvk*JvS^J8L^_?q4q z);;4Z!DsV!P*M>F>FiF*{|p_nUgy;pDh?J8vwO;emgOAAcxrgDXiSDS5ag?0l*jj< z(khZ3-)>eiwPwpb6T9meeL)!2C-K@z9fF`0j|t@;^f5+dx86R3ZM{bnx9Hm1O$s)N zk$OvZR0u2`Z^QP8V%{8sEhW~_xbZMad2jtz&0+ekxmp;9`ae;_f%-ltk5E%)VT*a6 zRbMnpCLPnalu+1TafJ4M0xNV8g}U4Mjk{le6MA|0y0rk)is}M%Z9tUU22SvIAh7`w zTysd{Pztfkk=jD^*!lA+rBcqb)Fx`A5iaU2tl&XdL1D)U@pLEXdu%#YB*ol1N?4ti zHBQcU#_%UqiQ1)J^u-ovU@-7l?`YzYFvA2#tM0mEh3?CpyEh_NUuVajD16t zyg$C*5du9R=K~6mCJ`W+dFI$9WZZauO)p2H)*SKpHVsIu2CxfJvi2>; zcit#57RP7DpSwMF-VBm|4V5d=tRgX7RM9%KQ0JRo6d<)RmiIPWe2zh6tmswP`fs^) zwy};#jk|NXMqCSfwIR3QZ#W2`(%sJ>qvk=53CYoLmQt9q|2Gm$sB;rEuBqGJA1OUM zoyl4Wy-HYn0J6L=cad8o)R!Ea^;`rSMg9hYo3?Fw6B9dUq75a-MSb56n8~AAsS(JP zZ!1khPu}!GRpsj+jvl`N1tDD8m1myJCI3c-c<9U-1Vg`xJO~}5_wvPXYh^=Boo^|V z3Tp}|lH!9m4Ipa_$p;b8fjUd=zc4iO7vr)M&Xs0_m$fgY@+hB9%K~4*9$p0d)m2bO ze5JH`W0fnIKdcW!oO#^g1YceSQ4u->{>u@>tLi!fky)o&$h(=he?Fe_6?}O~iSf(F zV&(P~*5h>BW{3e1H%8*7#_%L1#>W97b0@jHtliES^w6w5oldI7QL+?I(Pl$DaN>~d5nXx z;CO1E+S?3E2PLq~)-?ygkHAO1m&hOYmj7?;2XM!$D^f0l9K4P{n}mgb{CoYH6RJ8o ztydc6dNqA)`CG?=Gd~EIbi`UM)eyzGF^+i?&TOdyW~mFH_^Gye(D}clDVFQ@V2Tvy z7rQIaq8Xx`kC;AO-_{k%VI2e6X@bIy^mupEX%{u0=KDUGu~r6lS*7GOeppy{&I&Ly zjOTz=9~jC|qWXznRbrfjg!1`cE!Hzyjzw6l{%>X)TK(UEGi9Uy3f9D6bbn0gT-s`< z8%$Msh!^8WidX7S;)n2jh_n1-QCtSyOAKcPQc(Xlf0*Q|5CSBjo(I-u!R0GJgzTkL z|6QdQRrUMbUO|q0dQ%+d^4)*Mjbm$R}RUcz(7|E0Bq-bAYY@)OsM<+2>}CV zzPBgeD~kBHE(Y+@l2orJrdtV7XXq_V8IETas%7OCYo`oi)+h&v#YN!Qpp7drXFS>6 z?r-q7px+(rIy+bo1uU#I2A5s@ASe01FgGMbouFkhbkm-9yZ8Q2@Q1vuhDQ3D3L+zA z(uz8^rc24VmE5r0Gbd;yOrXnQKAEBfa3@T7fcF$#QYv^00)VZPYehpSc@?^8we}o{ zlX0~o_I<`xSfI8xF(WXO-DX1>wJ`XN?4rw@}_RLD*${$}UaXL=oM(=SDMIxZj1Ji#jAcrH7nYG`r z#ewodj>F5Bf9j(j`a;>)=*2j_ZN}vf!~Hq`2Eyt;9UH1_(yjq1OUO(1M0lI3FZ2j-fU9)L59v&OiQ>5$;d!jg?Fo{Svf5t5FCZbb?)* zJN=Q!?2BztV$7)CWtG0MO~Lr4E5>aoHD5N4(+@~gQEbZTc4s3HrIl_G23PCng4Y3f zbLZK1A-x9x!)WwuI=UBkQ5QyE^&Nrw?@fsRKK41G9-xq=#VyO%CEo`{_eioDj%M!3x=>I zfOPFiFX{1t-|+3E@?UuK=0miGN04hW0=JnJrEyWw{Bg-jMvAA}cg<5LN1c5BQdrIZ z#+bxj9Jbu`11@IUjU|RKfL(UzRlVB4XT ze|(WaxL$KiRqkgCr3^Al(19!_Y7b=E(4Xm7LCO$y5+k;Fu6B#=OSzW`-7p{zRv-_) zPr!|km?8aF}+3hm)QG92YaI+jctX&5IrvTUGf{Y$)TK6)s9v!SMhU=HIpEC~2 z4>o14mG$El2sTA(Ct?xS!l*x7^)oo}|3+BF8QNe;bBHcqdHVmb?#cbS*NqZ%mYS~z z`KLoq7B#KULt%9a#DE%VTEo4TV03T2nr`FK5jUTA$FP0JH6F9oD*|0z1Yf2b5?H0_ zD|K|_5Zk`uu?ZN0U! z_mL>>F;mnHU=@to!Vv*s4;TQr9y)L@1BXXz^a85NSifPTL4h6I>+m_S3~FkXB{N?E zS<3ue_(wqaIS5;4e9{HB`Okl9Y}iFiju+oTqb)BY)QT?~3Oag7nGu-NB5VCOFsiRs zs@m%Ruwl^FuJ1b}g^=*_R?=SYJQ@7o>c9j>)1HgB zyN9LI9ifwu{Shlb6QO2#MWhxq~IG!U^I!6%5}(sbi>=bq8!8@s;4Iaun#kvh7NPwX34Rjbp2f!D)cF&sNIO%9~;C`cs&ZY2=d@c3PpN$YZjUT}X7rY`dlWX$yc znw(7=fzWapI=KzQnJ(6!o0K_aDk!^dZ#)pSTif+jQtQXga$bPApM z=);jZ5c*?*GoeGMnV0=RrZucRRYBjx>tx`A3OuY)#tp2w7mh}&kj)SKoAvbbf;uO! z?+RItUow0xc*6StuO4D--+qY!o}Isy}s;ts5aM5X~eJUZoLOq@dGv=a4hHJD<* z5q{dZSN{bv_(Vj#pFm7Q<$C;MwL|Qizm~QCFx~xQyJoCOZ$`sYD}}q>PwRZjb<=E< zAeMP?qVfM>xu2}Il2xT6={KBdDIstxY-`5IWXN zUiWV&Oiy5R_=2X9Y$ug9Ee=ZSCaza!>dWBMYWrq7uqp>25`btLn^@ydwz?+v?-?2V z?yVwD=rAO!JEABUU1hQ|cY+_OZ14Hb-Ef`qemxp+ZSK?Z;r!gDkJ}&ayJBx+7>#~^ zTm<>LzxR^t-P;1x3$h;-xzQgveY$^C28?jNM6@8$uJiY81sCwNi~+F=78qJZ@bIsz1CO! zgtPM~p6kaCR~-M>zpRCpQI}kUfaiZS`ez6%P6%*!$YCfF=sn}dg!593GFRw>OV2nQ ztTF6uB&}1J`r>gJuBP(z%KW{I^Uz%(^r5#$SK~%w1agl)Gg9Zy9fSK0kyLE24Z(34 zYtihZMQO^*=eY=<5R6LztHaB1AcuIrXoFuQ=7&C}L{c?Z$rto$%n=!whqoqG>#vvC z2%J5LVkU%Ta8hoM($p1WqN}wurA!d@#mQGU5Nb>~#XC84EYH)Zf&DZR!uY+-;VqS< z@q?$ggdX#auS#%%%oS^EN)?JhSR4JYpSgGRQZD<9!YvvF+zp0>C#$!x*x}l8U|Bb& zv?v*im5Bq_(5Wi40b1^nKun$XTST(a8yOAcqQZmKTgGLo)Ig6JuEh5J9NnqJXin@Gxzz-k6xXWYJ&@=JZw=$+ zFPGde%HsR`gI+y`rtiPaMYwbtyp!sVb!pX~;c3zLoPO0eaZSV+O_z z%9H@UhqNowzBTPcMfL6kC>LRaFF6KVaSv1R@%4}rtleX!EMnL`rethYrhTLj1x$tj z;)H!fKo08&T(;i|FT&rPgZ*D0d=B2dXuO_(Uaoi9+vEhs4%{AD{Fl@4^|`X=PvH(s zI7$6bWJiWndP$;&!kSCIR1l57F2?yzmZm~lA5%JKVb;1rQwj*O=^WW~`+n*+fQkK0 zydInOU1Be2`jhA!rnk1iRWR=1SOZpzFoU5{OPpc&A#j6Oc?D&>fAw=>x@H7?SN;d^ z-o&}WR;E|OR`QKItu(y4mT)%Pgqju-3uyH?Y@5>oSLO2Y(0(P!?_xOL=@5+R7rWw# z3J8%Hb@%Pzf^`=J6fEJ_aG6+e7>OUnhaO1(R1<6>f}L z?d@Wnqw9?^;2?q(b@?Wd=T6r_8a@Z4)*_@Q7A`+ zW3w?j!HW0KbhxF%D`9d2HpvIrBxM!36W3Yh5=8_0qYfnHm*yiLB?Ay|V10N%F9XYq zanaDtDk$rS+|_H_r|a${C}C7b{E)Ii20-a?Grff$E?&|gWF<#Ern2GqhCiS0~Y%knIi8zY^lE4qLaR-3M;_Rkz(s;wu z9207W1PXIe#4h4Zw}dvdV&FYcnUlD5_C4hzJ@bPSBVBLpl$&52mi+wwH;svyVIzAB zoA+NQ;Hpqh?A}^Et~xhl>YQNQwh20!muW{ zq}|Pg3jHZWnDBN?r1KhiVG$%Sm-4+=Q2MZzlNr3{#Abqb9j}KK%sHZj{Vr2y4~GIQ zA3Mz1DjQ3q(CC~OyCaZn0M2!){)S!!L~t>-wA&%01?-*H5?nzW?LJB`{r&)vLB4!K zrSm({8SeZ0w(bL9%ZZAZ*^jf=8mAjK^ZR0q9004|3%73z#`-Npqx*X^Ozbja!C1MW z-M~84#=rU1r>p{+h9JU<#K_x$eWqJ+aP%e?7KTSK&1>dlxwhQmkr69uG~0iD@y|L- zlY0vSR2|IhZoS6PpfUai_AhKo2HfdD&mhv#k51CX;T z*sU)XbDyfKjxYC$*_^(U)2-c0>GJ(zVm$CihHKlFSw&1A$mq$vsRt-!$jJe3GTaZ6 z3GcVvmwZ0D>`U+f3i*pQ>${p1UeyF~G9g~g-n{ThVOuC#9=ok`Zgz@qKCSN!1&P`N z=pdlGNwal%9;)ujwWH*#K6CQG*fJDAQiKlO2vKJHeA1lj&WQC+VU^@ea8$#~UOX$*Q!V^8L- zL0$W5(Y3=??%&j_WUq6*x>=?BfmI*d8fmDF*-!XVvxL8p7$r+}Igd_(&`|D*;Z#GE zqm{tHx&aHBpXw&~l6>7-FlyiSPJtTJblAjLU5Ho$FeN0mDguFAq?r+6^~o6|b+rfE zGVcZ&O-X~tE3liGcdI~hHSCT+&F&uH8rr&f{6pr^1y5061`fu~=^_|Idrgti5+*U7 zQOb9G?Rz$j-G0Y}x+i{HB0!4ZmKzykB<0;Rbmo2)T4|VdcwujI_otLG@@8OOKg3kw zP|0ST0D4@zT?O=(0Pikp)Rpwxw_VsmW4!^j^sFd6r5l zw}SG_HQPs>ae%Bq{sye_SaBX%|F-}&^)Wz@Xi<)YNbO?lPs7z@3c;$b^Aw@>E%mOj zW^c%IdtC(Kk@s*}9NbKxEf8SZtP+32ZTxjnrNWS7;W&D~ft{QY?oqOmxlV7JP!kW!Yj`Ur{QbbM1h=0KMaIAmWiISb7TKd4=gMeo+Tcz2>e#NihnOV%iNdx` zeiuoOK^{}D+M+p(Y7EC=&-`$B0F< zQ=zHaM;&QQR4jM$sG=N&sqOvD_Bx*drQ6c@u0()g05cwl`Xm{!S_Nuaa2KlL*rmmk z51yPE)q?Bl$sNM474Y!=zZ zc{EVGpdJ!Su{Qq%llR5O6#zK8l(ld*UVl87@|iaH@C3+*;XBxjEg&fsQrzpMo3EEG zv*Tpms7a;7!|iz8WY7={0a$0ItO-(ajXl;wX_$$yzEF5k9nc>L3wv!p{8h2)G0W?h z{v6vH=7+>$Ho^+)9hDtCd+S_yh8pzS9$)hYev-=eDu?lGIR;-fgz+dr+wcmM-^dZp z9}`&kAf$~z1ovF)>Hgxc!Xe3cju-jQRluCm;c_1=PYQygb?Oxe z!QG0L3sT_k=WpfOPL#|EPlD^t;ENCC39O?tHd<(kfx7SOcxl+E#;ff19_+{vbkZSvbS$I{#>31KZj^$n%ayX0jj}EvsgnHg16P z_A6Y)pdp>kLW<;PtR*Vs#mVb%)ao7AXw{O&hBDmD;?mc3iMH;Ac@rZZ_BQa8CQ~|0 z&d1L{in-z--lBO|pxqc%bqy^~LAGv=E*eaVU~OeuVV{d`Vv#-_W7EYdTDzVraG9H+LC_dWcgZMn~KcP)XvKWbcr5&d+=a>{*(Ha6Y1$==bR z{O-?$7H;`2dt0B%Vm?6`_?ZOjJkyu9ZJsh^WH*+es&^@KDcR%Zej%3PJ*XovgyhTbaH(!H1H_OF~=*f55Jr8A%uW zz5IoAB~1e2-tDGp9}`MnavAMy?jgPM5F%y`%$}dFLrz_* zIrO=afT8+AkK5B1s3{ZDVP$g6y$-*U*=?-fh!cNyn3q6YhNhfRxW&GLIJ2#>9bYMD7-F%{|Iw%@a=DoAAU;3k9p$`V zImKm{5HU~wq|nQFwab)_7lNckW#1z2$|oW5x7vDbBURVjw8674P?L1ogMKpHoV>;# zO%*1OwI|($UOr#hL(*M~qsn3PF%_|15uc%Hy9@D>_~N|?<%lig6yKX0a#1s$o(^Laj8bF#5fGPOFMGmMiUaxSwE}Qf#SG_f79d2Iv=TFBXzTpr$^avJ?=|arh2<+ce}&248Kw0} zhlva`wD6X~s7|37la4FnFOgIHhBiFo`lw~?lSbk{>)P(3jyVhM4O)a=GX3(sW1vIC zz0mJ>;J{!eN5#nf2>$u=3Kq>`7u9QnChi8>CjONBN-b+W_UQIuN#{N$Q<$}IOvpQP zB&5ZrY{V&D=4)voh;6<1U`PFA>V%XUW73S9D^J>cQYfzIyIV5i35WNb5K9c^|M}=* zN_C3rnjCZP1^v{;EaGK7Tp5z~B#?f5NZaAsFUOLK)mI~bJTaL8DF_eRikE{%^J?y9-n_U32EKHPCkB^ZN2*zk{bC=GM%_I z61}nkr+Plg6S0V=mY>H_KQU&)P~=y3$#$*U8FunXkb_e1O-7t@m$5re%u!_G%^?_| zRIJzg+lX$}+ba|qx)Ec6c^ip;`_QfQrD~SPa4MoyRUOtX&~^XWcO^a}KBkXK9J{ZFOA~rovYa0!7btTC*=xNQrwJ)$Eu`TT$;%V&2@y@$ISdNn ztbM7|nO+U9r;ae{{;QiNEYpe4nrFq_x3 z4Tvf^b(I@_3odwhVe!aC0X&~inrYFu# zh)+eF__8ly&nLr4KlLWl%B_ZMo=zCH2QfO^$lJ zBvU*LQ#M(5HQ}2Z9_^y~i@C#h)1C*?N3v68pY+7DD09nxowdG#_AAM5z&*|-9NcB{ z_xKUY>Ya7>TO#Bat}yM}o(~8Ck^!QHnIj8N9}c*uyIs}IEqGn`xP;q3vhW6gsqUe>`m1 z)~ad@y1=?H`1SNl?ANCs5ZD`8tG&Hi=j|R%pP(%gB8pd)Q--E?hWU@)e?>SLV4s(- z!_I^oVC0x97@I(;cnEm$ttKBnI3gXE>>`K?vAq~SK?0YSBsx{@s1ZdiKfFb|zf}ju z7@rJb3mC{U`$R`YS(Z#KyxQx_*nU`kf;}QL%bw17%5~6!mMao^-{FFmX}|ItFuR~F zAAvTF%f4XKYo>2-PJ~ro@Ly#t@Sf69CrA+rmMRpihqH7V&SXX+$Sw`HZF`I*_3Vjz z%kPMyN0J3sl>X{-h12)j&XRhAAI;Aou%%z}gI>G+32z*qpZg{m`CezFrzg#&yc<1` z%j~}PN!F5Ddq(>R{+t0v{j6v^0XwWGu@5+`-$m`_>pCzM`r}wz*8Qv=$|P0R$%tJp z>D+N4GZ|Tg>XL<6XP9_wQRGDs^1icY*5GP4>*7mGMr;V zI%kT_^_SQml6$#uRE4Ps>}?ES)_XI8m-%GN{o^itb^S7e_bM$-wo_Ws)W? zx4_6#*X;T$n2N==N0#xzb~BQU#%^NF6|~898JGDbQxjK(ex;Q}_Qn@?Y>!kkUYUeY z&VclG1#eDPU78K@^p3tAUvZi1(nFfk6AAVHWt)Wbi7dPbjA4isOY~?*1&asp!wg#Q zSpSI6*!TGn3|-%vuJE<9V_1EKkz_0%z}Mb7;E!uz)+0^k;@x+<5tzj5 z!InbRtc`YwNCbCac{plY&Y}hWp#PC{o@5UsBj#tv3f^ns^`;$MVN?>q!pW+MYeC7= zkWr1kAX(0xVQ<{qny&CO*|g1{Mk_yE>1t}_YT<5#p8P7QXf;o|s>XQ#SoA&!ddE+8 zOM&VsxsRGS(Spli?P$^pK7Ty{v86RP_6h|MU^J z`J>vn0|BG3Vf!uR0zM|GwtiTPZNb;a@@1+V5+$P4GI_&$%6m!YRGL=lz5kh?z#5f55 z76COi1`R(5p69;ThuQnJ$R3w?I?jigai2arApagd=^tT~oMUWp^u|H_@zXBjpI)Dv zEFc^_`mVu5U*;ClT?x-t9{#fto_+92GF^dotz0sFWTDwZ`s40AY@mv+Qh5c-Ts8Zp z!(v7!zPvFhUZ-xkR!IvaW`{PqN|k)L4*anbtmK+UU&K*awl?DhxRalbtmDw`$#VzK zYFaG}?$F)1j`Qx7wbn|XzMJ&g@3Ai#u5M?%CLPghk;lD^)-|21{Sr+M(suBU4}6CMTMxc_tD;X;z<1-{FeHte=kh1B9O6Hl z!v2i$d1VFC&z&58zU0`G#7^K3Cs@9LYN16O%Vz)?-iQL!G6&sg6aaX>DBZmm@lFrRJpcL{K3(;+`$9GDFDw62Mud@LZjabzVC=w$dx>TQa}U z-{dhKYTYx*C=Fio`ez@wrzx+p%Fk3i&v?6ENXMb3p^?;_&huLLueDwr zpRqHbU%i;9TmexFxCS8F1rPo-ea3!}!ew7{(($76Rdnfa`~$9{8H@f7U&0&HjZ3TZ zuBc||%FljS_e&wNZ$1ezT$*})XAfm??$_cY_?13vM^tT0EKY2ptb+v5P10}a%aTk_ zh8@_T{ns2@jTFhv`)-Vxh}u(0DiL0MUi(We_eic$;gCoqj(T_S{jDo^PahnKJUp3@ zMOk+%weP*c%K6VFXR2icY`J~-&fVMYUg6fsFI->jlA|9`+07y~$Fsz}^;w;mNk$ms zu?y)VA@QH__tvYDudhEWuDD20H&uvrf_boY{($?5{s-SDjyRxSC%%2Xs5d2dpjdk$ zU*NURD#ovwIfd^H{fXR@UuaooJtQr7$d0+(K+1UEwtG9_T?sb$ExV$e-bpf}a@YUe zuzInI59w!x;<)>Be;a7ukLW>V=8~J6nKU<0@H+SQ!Be;1Za_pw#hiuW_PMPBo8W2G z*WDtiIAN<>HQOmh)DMi{s-0H^GmV3QMf4Zu(zXT!-c;2)uv4gUwt(-}-N*|KUOo$h z+Ak^R)h8yB5UD8 zsSjHgY}KguNi?xV=tdCWqJR!~dDpFQoRJOwxrWH^vfRq4%)v;sDfIjsLXF^)uy>!i z*S8Njd7yfa`+7(|8H9j73Rh|TwFpF(8H-p;RLLIU>k<*qI%A*SL{u$%<=X@Jm1QFe zVkQ(X8P4Tohl?_tSO__^aqaI?k$CC8uNLv2mp_zD@4oDaZfEN5;3#XY!L{8B!;Dtt zb~Zge@JF|#Gsk^5$-|(OPI73po|WZh<`UxaH#Y2!&p05Ph?H)d3Bc3J4sDi$f(6K`?&D&~eHVuE@_Prkt>_&8&aq=OzoN!ANkvho;qIX(g|d#EKQbJ@;-%_iARmgSF1fEK z@B4W@5mDME7AzfL**c&2#B7xO9>rA4x$rM{N=%0=goumK1kL{TF@CSk0yvqR2oo&m z)?nyiL$9~Jt(qnEuWt9Hc_duim%|zJQYiaF*~orVNDvJB;`%ZW_2x%Uu01LeX-JP& zD&fas6d3=igAgcfeki79{5!XPHHYR#nfLYRKv^wkv~cnEbLHMwQ8%yCZI^rK!D2qT zk40Vg;e!_!3d56&umIuidN?6MTZFzHot}AdqKzDh#w0s`)cV!2A74RSH1@lDXtC38 z+UhO4A9?oZEOV{bIgGd1{2qMR&xT+}q!=I8m)W23v!W2WPC?Tf!F!e%_(m^lQZtq* zYwi}gY(KZ*Y^OWRNj$Ph#uEEBM+wtN8QFQ@^`GDOln^ioNrmtvzNNi*qS5lPHxI96#sMil*teLVaa%$msF>@5p#SjT%q8|<4ZOUB#!-kG+|eFSED z!|3c8fXaym9qH`L;pmqTWcG}WE$(h1sZ3seM>)E3ptoP<;~h~qe6XA)lGVanf&->P zjZwi;_;Dt+bYdAeD_XSQ-DgXRXqLv`3Wcgl}myA-JlzBBIh zWq4Q*9#(zjAk_H8VS_AJ`?OS*^gB-rp|~qt;v(C5ef=SErv;~zL64hW`#g!UZQcvZ zF6Ra@S@YhVSkSWVAY=Z1w)w-hfJDRwKTUH0o-OG5TlW0HDH36hIjnP=?A+8u1)Qyy5U8Gi$! zt^!vy|f=YHfQ`ZRK?D zXXn*kItRg50vr2+_hV5kjOleg#s~z(J2p#`=1Tq4#JS`MC^e4p&s7Ir=3m(K$LW#` z=ULCoWtna!so+QQ*JHb~6Ps9_&Ag>9qsUskp0pKbi`n?(u3&@QT!?}N}rXn z>1eHi6(@LicU*AR1obe+nbzTCD#VTJ`PFLRT(nc$NWrhsgRwFni*D(#?W^x=J6?|b zENSc^D}s>Y55)PzFs2d_2;yh89E0ZIgs&>6JV=pL6k9g_(`$04EoY+Zjn}}8e#n83 zJ=zB>BU<253Erdo$wE4^+@QQJFZyAj#(InFlN;!UGg96R@{Y&%OlGG;dM)^X8=Ddw@&2Vx?zui$tO z-{zgaU7&F!xs=e`Mn}r+xrdIAmkraRN_7P1?qu1|TZ%1QR(Mn?k+pq`Xys2v9Gs=a z?r@g&;UKcM#?36r9k*eVD(}9qe8?irotsn0+eHH8*4 zPX@Lusr)$J%8jarx5ssEJ?twFyu4kAbrf`96_z{6at^&UkyDzFa69RXP>PeK+dAWqE5<5P+aHa zs<<*+OO_2ObTXau%y)Nn{(p5`XIPWlvi|asjYcui;E@)Ig{YKBXi}spqC!-P5owwL z3L*+9;0C0G!xoN;4KNfDaElv>1#DMDglI&MAVoK2+c2Pr8&sl*1dYj=^>NRS`{O&%YV25@5*eoOvpD_(xdKsnqb^`T}bm;n0BN9ben1Ynyi*OOf;qLpf^ z!T{}GzkXSszN_Xqzp>}S*Im)_Y8~2|B*ybw(U=Q)5_NcMkT;)1&52YQJB)Tn%kPK! z@3;^AI){B(&UOv<{v9KKJrInkdcXV0%O1%1=7vYV*j?v(Kp~arZio$#(A@$kYB3aM zRdm4!^Je15%66($EkCIWGhi@=kNAyLJ3ydlJnCpPuxH0+OA}J)+t8d7nT->##Nz4w-L=S7ExQt=Rx}S*mpT91(>t~qe7tM%e|O)TIO^dP zfo61GNS=cJbLutqUh84?7X#bq)bv57s&D_zm{+xNv7vHjb=_}j-Lrj-Ss*pcD@ts$ z)5Dol8Z_&*1@JdAQE7SL$*!TXI|YE7q=YGkIiUeLvT0)14Q-ivs|+cqeT6DTi9eQ)h?Pu9pqmH51B* zFMd|;l2@D4*56|EhMFlDxl2i<8qq=c+AhMYS3(A28#3DZ;_Ln>RA3q#IAdJq7M#N> zTZ8t=_>lq0=W&w|bdQ^sy&m^@KR)mNi3|1<6|OL(0KLtP#I6ix$2b{-Y9GP5I7 z8AJUSCnlia5vWawX%ZLWTC2UV$cn^sfv68W!6)QO;ZjnX=7#`$ZPRG~irfl)ZUJ^D z{lUk?(*SU7XIiS^H{Lpxn%542#PgxdeG)Ociej#(uvX)z;Z3)<16Yhd z-sv?qQ5D4a)ZYoYPRep2Zvom@U)HKq*54ZEwdaEq^FZG#(CyG!=Vw(0j8CCmP~`_z z=OR^i&WkDCf2cLvWm@d?)mEgme{hA(o#xAL023LZ3(82SGRg6jJF7$kZ4! z6*FTm4y6v~CP!3$+fxg{QeFo24<3iucgI!oyjV|9Dsx}r~4X@lt^VaH$u zD?87}1Jh=?G8OYg*ts2k;X9{f*Za?yu8IUUfyuQ**wbcWT+KncjD^qQ3h&w2+S(Mj zZM~?Ot%ggTIHwkBkL-4&jI5R=B+MCOR42bKzC2M>l?1%x2Iv7amIfQ1B#wwfD`z|m z+E?G+o(tde*Ws?;Wo4p#Yy>Nnf|*b<nj@-s(rZ)-U@ z(Xe(qZ1(_dH|J3yWu|bAPINK}DwF(kZ>FKx(?ZmU^KFC6*bh$;FKGh~pH1 zozA+kgcIk9@2aAwEJ=VYizT!sxDXX$N?XDiGKaaT-OU@Ib=~4DmgEk&{2D@IvyjF* zuF@sDcuuqx_FAgx;B@@8gqjMh!kQeEKA*y4+q+^4&uc0|>M;$Xb+ z@X%eUx1m%$WSP}Qchx68NQ?dO!h`6;Quq+A1(RORsQ-;6bZ90vj#^0(7>cLR+-_;9 zCd@b~B5V>$tpjkQU#BD%9^zu7-l>U8nzt+XuX5cYDCHYaX5t~~3?lpa;)Mr>q;5XW zu(Th;fr}-GkP`K)u97(#UB|L3f;H7Cd#Pox+auV`=m?a=mSv1v)(V!E=$%gkIJZ;` zZj{Lb@bhs%bRa znZw9cD$cDFVHPtpXwY1K)wys@LS~;!qdqkR>@&RtP>?M^>xe{4N#EtZy4zZ5Ar$ZF zV=X=(!xin-58MC<+b~;jk8Q|3B3THGIA$cM8Bg)Yd6ygP#i?4VrX3OvP_k5i{Cppw z-{$XwrJ-+X$ccJ(Q{|?T@U9=-?qlsfA43%8t247KZn?`+C4e`b-e^(df*iW66=Oc2 z3w9UhohfdY@pH1MZ}vc<1osV(2CGG)Ree$E-T;8>$zw*>x-505b&4(shMGIjbAfLS zEZ3ys(`SmCWc(75)^=aKer}>67qj^nGKtCK{35I|tA}wQa!uM!suX%Gb~ylORGGc( ze^|m|N!}G0#Ph|;wSXz`SByQM>lPM#8>mdSQs`7RxkXaSAADYA24u6xWqkIXY?o%z z%TEFL+wNW^&nrvaA1_#P%&Hbzrjl!*hIft>F0@g0IVydUU4MJgS3_3Js8{*>|G2jC z4%n#cOy9b2Xf&Pw=14;0Dtf00C^Z$I-v05OqtvN9>sAC&oV1Tk;;ku7VR`sQK4oFq zQ8)yoZNuTwV$t13|GCUIC{ID_r7M5&R*zhsxbrkg;EgMtL|9ne=^}BM!dxV!KDeXkWA^MfQTkQEt8~t>JznNh%ULvn@dbQ2cyf} z|C%ns#NJU}SHU(7Pg$<&8uDK>d5GZJ&`;CcfGP(~b-#UusXevc^q!km1X6_wVMqGk z^m&ZS6#42?p4c_t1TA$_+}h1L2c<<=$k%;v+D!<@j5hs|{>d18>~~v#oq4yGyS@QP zgTX2oJbEy@eJbo-f{ZQ>-nmB-#AqWcHbMQXFi*T)0n!(HIexz=pp<(O*DMh7CMupX z)ei1ZYuIW~E={-ND*nD;okiZdm!?^|LjLZhs*FHZvWld5TDj zcvWB)`-1Me9bu`*4M=CO6ye=pMgxlgYvsh2rV#5Z$hFKw0GX30%oufb=hJ0BFIJH` z+Fii4gQ+7!)8K^yc*PVEW^#f!|BW0Q5*`IewQ5YDFh?{x1L7tlaUAX@3Y+D>6FPVf zJzOGex~H34`8eq+TL$FsHm+27RS>3$CG;>0Jj4*1ukX$za})*b^S5p}I2jbFCHLsA zzYwAyftMz`uo2c8ieQcy-p&9iP3fMk(uRw+OlBPm`KCLei6g!|Vnk*-kjs>A25MTE z5GLDMV$70AC0j-tx*0sCruvKh{fSM)3X}13U>m|KeaOb`9^}v^44!$`06-JHf@L4EKyxV)M!8cL zi5p9kF97RiAT92!e?%9CP=qX3wyv^A8q!w%07d(9f-U))uDgsr4FDVL;|%r)fw}-@ zlB$F79X^EKYF%8J7mU?3VzJoYQ0<;NczW1jH4=4kEh_)q|^9wj zIsn-SsmRx0_EJ7(6WypwptIwZ)-T<__UgUu?BXt zoIf|a!5`?&JEb$w2PZSqhA>J;GIA^rJ-Cpz8MKX~bcqZNOUzPtu|NMvEP>+cO;V*W zNQ8YPENkr!)lN+tlxB79RUD20$)+_P6Jc`+4q@%Kno{F+#1qR*zrj%T>nTSceO?a5 zyqGDa59#G6k*RXu6+#=e=e!~i1Y&15!cHmE6sLh_K%Ppv$tFE-Le3RQs-nx5LB>gy z5A))kwkxWSy73{@I{%{DY8X+2o{CLJb~R$3r=oT^P~Xo$2lKz8?Z!3QLn$5l#L2k2 zb1=?UT&c<8!&9gW1M&jI!5%dhJbD3nQXpaeNJ>=zR+EL!4iY(nMBQI+|2J+Hw-WMr z08Mt9h8(PGbY?zKtk=cqw(yW}1A#htn* z8&}5Y>$uc>Lv!bSuWQ5UB&ct7*jiZAFpxz|%xO&5kg zzlf?6xy7H3G^*wvP5scW*Wf(<&eP!YIUf%&HT?K)RWmKg$G^=mSoi~;&9dU%{o}WV z#BX;9+q)fpVU`>Vdo~AtYK)`7z*H;dc-e|q6Qt;3J0APUL!~g&Q diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png index ed4cc16421680a50164ba74381b4b35ceaa0ccfc..13b35eba55c6dabc3aac36f33d859266c18fa0d0 100644 GIT binary patch literal 5680 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 literal 3276 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 N;OXk;vd$@?2>?>Ex^Vyi diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png index bcbf36df2f2aaaa0a63c7dabc94e600184229d0d..bdb57226d5f2bd20f11934f4903f16459cf52379 100644 GIT binary patch literal 14142 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 diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png index e71a726136a47ed24125c7efc79d68a4a01961b4..326c0e72c9d820600887813b3b98d0dd69c5d4e8 100644 GIT binary patch literal 36406 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 literal 14800 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 vNcLuCM3Rj?iBw@67X_p?_CF#jIyB-s + + + + diff --git a/third_party/example/macos/Runner/Configs/AppInfo.xcconfig b/third_party/example/macos/Runner/Configs/AppInfo.xcconfig index 72bd0c8d63b1..8b42559e8758 100644 --- a/third_party/example/macos/Runner/Configs/AppInfo.xcconfig +++ b/third_party/example/macos/Runner/Configs/AppInfo.xcconfig @@ -11,4 +11,4 @@ PRODUCT_NAME = example PRODUCT_BUNDLE_IDENTIFIER = com.example.example // The copyright displayed in application information -PRODUCT_COPYRIGHT = Copyright © 2019 com.example. All rights reserved. +PRODUCT_COPYRIGHT = Copyright © 2022 com.example. All rights reserved. diff --git a/third_party/example/macos/Runner/DebugProfile.entitlements b/third_party/example/macos/Runner/DebugProfile.entitlements index 49a43de571d6..dddb8a30c851 100644 --- a/third_party/example/macos/Runner/DebugProfile.entitlements +++ b/third_party/example/macos/Runner/DebugProfile.entitlements @@ -8,11 +8,5 @@ com.apple.security.network.server - - com.apple.security.network.client - diff --git a/third_party/example/macos/Runner/Release.entitlements b/third_party/example/macos/Runner/Release.entitlements index 14dd7d1be27c..852fa1a4728a 100644 --- a/third_party/example/macos/Runner/Release.entitlements +++ b/third_party/example/macos/Runner/Release.entitlements @@ -4,11 +4,5 @@ com.apple.security.app-sandbox - - com.apple.security.network.client - diff --git a/third_party/example/pubspec.yaml b/third_party/example/pubspec.yaml index f90020e36941..a4f3c406da1a 100644 --- a/third_party/example/pubspec.yaml +++ b/third_party/example/pubspec.yaml @@ -27,11 +27,13 @@ flutter: - assets/android_vd/ environment: - sdk: '>=2.12.0-0 <3.0.0' - flutter: ">=1.24.0-6.0.pre" + sdk: '>=2.17.0-0 <3.0.0' + flutter: ">=3.4.0-34.1.pre" # dependency_overrides: -# sky_engine: -# path: /Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_engine -# sky_services: -# path: /Users/dnfield/engine/src/out/host_debug_unopt/gen/dart-pkg/sky_services +# vector_graphics_codec: +# path: ../../vector_graphics/packages/vector_graphics_codec +# vector_graphics_compiler: +# path: ../../vector_graphics/packages/vector_graphics_compiler +# vector_graphics: +# path: ../../vector_graphics/packages/vector_graphics diff --git a/third_party/golden/dart.png b/third_party/golden/dart.png deleted file mode 100644 index fe877e7ada54b9f482f6f064f95e38399c639277..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3651 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 F{{bX+x_kft diff --git a/third_party/golden/deborah_ufw/new-action-expander.png b/third_party/golden/deborah_ufw/new-action-expander.png deleted file mode 100644 index d75da023af0f69c1e10b138aae6af50aad91562d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4655 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 ViQM-l| zn!M5x1p%cPkfyY}fZ})keSdv3zxnRWy}M`j%dE|tjVviw2C@OVO1wQ~peC?3vna1d8OQ{y&D?y!>*wIlSo!##ds|m( zcZRN=u&CZsm&Df}Y3YcEB4h3y7|x$Y#t5l{g<{yWkq~1h)(E5oG8Cr4{AZ(u2?VOD zstQsJg(GRpHCv+IvdL3ZceKZO#!$>c5FX7@pEEIBo$wPg4V|6{55&tSqXQh;sTzlE zviuI*pn-vN0uFkB@l<5BaE)rt+@+jJ!S5fJr0S3Bji=@Apj$kyfnyi5BCsExJ)?*( zD!CU)uJLMTJQ(xLookn?IYRY&I%YgjX{oyr+T*E5V6T}=kf->dMlU8Kp#gvH4-Am3 zU=Wq&hGtCQ{MK(8QuydS(7A(baAO=_N=`9*<~H*i8gYxGraFtNJ@)AGbtw2tu3}St z>L=He6ufh=jQsg+)##)o&Whos+;DrihZ5q4q605)e>I<(b;hN}nF`fBgM>+ay`1q? z5x}aG($#(LQqvsC4Q!IC+muho-zyiT7y>)qQ7vifhpRKLr(sOdOjB!DS;LJ)X$nnu zs{|P8{hmh8?^q-CZ6&+q9CMQ_cdztFZ#+VZ=4@-drXfUcO;Orbz3d6Au%AIM5jmplUu@ELTK6Sf zE4U!n0!9X~-mx$+Up({o{N|#8_go@4?%fqnC4@FYrcYlE5E>?A4b$tZ9+Erh^oPq= z(}lIODPo@f`C1FefNqrj57nyuJx$}!-nH&*kZw}DmaQSIxpTjB2y)+&FX6n#Ru+Y| z_S5VAJsmJHIJoLJHgR#HEdx2-<1;%wHTQin9o+fPO}T`NG3d_SUhAM=uP|?RIL~2Y z3PNVX%fGLswPufWef0>LbY|W;Kpg)%xIOc2NBOn6q(6!DAtNe7p0cbA^7!2`vFiOw zP*6GNJ&(hc*y`>5eTuXqlY?H{yLWi}lq#n)zzch_fI5EqyDm5B1E5G4%?nz({LyTp z;XeowfrXWZK-6Ho$rxxMm>Y^U#rz)_Ju*EG=@5zt0WcKoM&i|E(lq`h=|0flW=HPy zYFe*()+3vYLG2tKvf;DCVBiRt)%|otKhuBEq%!?kUIeBIglA^vS?$!~`X4bUeIfmE z0uy{3^%rfnXY)?Qbzs4Gj5ym+Q-jgtbvj`vl)yoj2ZmIKi*DyhW1f0L@Y!8XwV?-r z99Y=y#YEk>LeS8`0c!rI|AenXm0{GvtyGM&hw6FzYKso%dS~e#YZhXD_|}o!^Wm>Q ze^&bxSY%963DKtIsSp!vHsy^~MF-@H*e{SoqKd^C34YBGnlL!P53X`eC-kod@=Wt4WqLNp~ z+ROOe_6H$7as!$=HgEpP49$L`OD;ln*uH(9)5&to69Evf!OJtRn#Ue{46&pi);``; zLoP?yXd-CK+!3&F?!HTjimRlqMPDJgvB&0756DGf73lsyK~pG;Y`1FyJO&u?L& z1>P5{%a^wbt`I{@i|LJ0ry^iQQnC-TMT_xl_HZ<*&%H6n+Yu`$DxLhBG_ORV?x@1l z$W9Y)`$+B4~|I5r)1k;u2Y2I~B6w&a3H}S^1$DVqzds9bx~m2_V7fsi~=2pC&8QL=lS= z5!~3y@)ajh-uE-brAqa~AQK&as2VC)Gtm(MiLLuytH|-oC78~{6)L^N=BZAlU7`G?@qe6Z=cdnT zret&*kgKVR7x>owly;3HZYBR2cideejMErF13L)S;oAWQ{1Kl}R$o$olai({0HG~o zUUy42Sp;Xa*#}Eiz0wy#;4m~aqz+GSF%mKwf={fW?eFOoElrOo@SUYKxTU#_^#A-Q zku4?j%c;T51<&c*HP@#W%`wmmR(jcA7EdRJ#}CbJF|3>e(_**0>sY!cF0U2wK|ipZ zcZMx|^%zNQeoCnPrI;a*=0hYBjSpK3t~iI^{3Dc zlbU{g{X+6qp>~O50r@Y}VvEa7peo^@r2Zn47I`-=HNAa{%}31J$H#Y%tkQ!xUrW9W z+vG*3^NPN6!G7YY>$NP65H6*ptjch2WhGWyrQgKvCCSL z*Ie&B?rRWjme@>kR#>kFK!_5=l6)nEG%kxjo@Sdd;u;vaKh+!s@rtB15@%X^-ELf{ z6(J28brYKJZ-epF5={Q{=hk`gD=Po)3P^06-(kz=5S50dk0j`3z7mW3Fm~c9?oPym zSF|^7SMZ@Lq@(LMZ@TzJ0!g1nj&!ge1LMQrI~8rXNku%$b!?G*#G&@WvcjAyjC(fe zv4SNrvfdnC7Dk@1`s1oeGU`gQo?C=i$|J5A zdwAY4$Tot63R>jwR5qh~`SD7mj5l+sJz}+(xConRxV8bO;JfV`^pBJJTiMaXZ<3cP;1sm5#(@=;dJrd$JAy6P<05&s3UzPJvUAD(5bv0R*w z&xS?WFCHCr$+4G=a^^IpLKNiWZbBRMx-Ma1WOwcWB}7_=t$eSi+@~-7eUF&K_A1O4 zp2HoAUWHfN$fVn-yP^lhU+>#G)Pe2E1qy%4L^Xg^-Y`=!cBQ#Pj(vHXXez7jNK(ThAn91gAeH~}RPw&9+CJg9@08!;uicoBi9J}-as3Yn8+Froe zCT|A>vY^D_%!(c+NUuJDJ0K%gd=}g-`HJzcG!ex7BCRBOE&hpbRzWM(6Sz#1zbUT% z9lwLsT1mgB)Wh0m83A-3x0YGz@UWpG0N(VtZtz%IZ^COd9trR~W0|1Fl&!jwf#@=moE=u0tK5gRx zxnLT|zx%!`QIPFZ`k!+f8yi1NpV3UQshUdY1x5hZ@@xLFZZj*s^+KkzE8GLcHQ63R z_Vrc;n?!&A5WwF&G5)YEI3M#8A0SiYAx#FVSvmbPK$7bBw7S{V{K<7h-kG-SRTCQ9 z?xnBnfWQ{_yi?Yxb+cZJ@ME_-i`H==pvGe>xg2+Ct(hJ}qc1^`u$7dD{{XAhetNNW zs@r4x=zON00g{48Pt##)sP8C;qB13*n6LQNo%}2p18P%zlbvh)CAa&2^~&{A_pMR9 z(f06n#kzvvr##ROM(kTr*0VZ(F3uN;fq|~7YMYEB9A&qx+mX2o?h+`Y24#xxEv$c4 zYiq*8?269m+f1Po8C)h_k%MfIFV_qt;|gyvz7aX%d%=RwQ6f48iatqFv~!aaZwlmao+}-UH#z4Bu`c=;Bon-L@aZvNNDfZi2jqUlV=qCgV*)pi~A{D*%x(1Ys{;JNd&(2e+X62JQ_)XKe#k-f6Ge0L_yam0e zJBYyf3uGhe@0^3c%2poTg?|Ej(vFyPE~zLMh+Slx zx^L8XF5c|y@Xop3i+`n@SNnV;w@~hbXG^)d^Njk&nVQ$;McGFog+yNQa-mgrS@A1M zn~W!RFsUj$$_O4mrh@P;1MCp6j z-qF3@@>dk#QhzmDT1M61yF0(vS4=1R381!izLc=gK5>q2$I}b+#Pq45qh1C@M zAo`0Wi5>}Z?8CG%2nY87ugz4X>af;^FEO9RG9&NKBve%-Spb3sX&PgAG>hQI?A=PI z!U-flEk_@9a9QluQ8Hb*$CIp+HOpK3X?Tm}bgb9N6nA?!qSX?YhA4ah+wqDz6mWeGqp^ZEzr@wOn zw?JL;cu@Fu`%l(v0Ig=|tHjN2^B8xb&^ipij+fgN1L#i|lb9B&g%Y!7{)<$S2ID1LbCB7EYve?}P;!OuN%pxj9+eC7bd!Sb)C(IqO_BXy)reSMm8g=&eqLB!F4?bdJoE>c+ufXaoQ*t$C#yw_s953SMby&;f8umig4o&U;sb+ICd!yKry^50yNzcc({L)u0wq ze5FsEYAq`U11s{p*Lz-yu~}4@Tlt|_7Zj;&Q6=urE3bxuzG!iQ&f#KwxztbrTvLMA zL9l8IfSxCzA?=g;1a39OTmmprLMxByJ@;~@qmrgd$y%w~Vy6vZCQg>3wo`7OIWuXO zzV8@;2W#}sMUB4o1R;awFBiZb)kr;U+mhV7-Yqv0RJD&N22?+gx;s8^OE$QLFDiX$ z-c+8viA@6{d~0hfS%g&tS9pmmp6IaKz-)yC&HEey1x0n^Y=r!+Gl$pcR(Pmc!;D)I z5k>7ijHMHGx&`?y?|dWP9d}R63Aed#X}%S#%5RxoG3AmjQz;4)$BPIFRF;tu(~yfL zX)_xQ4B2q<`b)P)Ye8GT&XDPGqmE;#_?#1@YH+&*lkcOZhF0IgROYUTLm|~ z^C(e`;u>YIJ-oBD>ixZNZ9!e%6gR%>ss^1P`YjyGu`ePrOsz7#Ws>J#ye9WN_Lh#C nheu$b_e+hoo&Rgd9P}5 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 diff --git a/third_party/golden/deborah_ufw/new-gif.png b/third_party/golden/deborah_ufw/new-gif.png deleted file mode 100644 index 7ccc6719cab39f787052016df29e33ddb6f07099..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3143 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 diff --git a/third_party/golden/deborah_ufw/new-image.png b/third_party/golden/deborah_ufw/new-image.png deleted file mode 100644 index ea30712bf45bb01dbc7c6ea67983be565eb84f43..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4493 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 diff --git a/third_party/golden/deborah_ufw/new-mention.png b/third_party/golden/deborah_ufw/new-mention.png deleted file mode 100644 index 9c79bdd4a8732933ac23ef81c0f2db3d41587589..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4420 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 diff --git a/third_party/golden/deborah_ufw/new-send-circle.png b/third_party/golden/deborah_ufw/new-send-circle.png deleted file mode 100644 index 4c96f358a27ca8106bc63c69b2d1736467dda575..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5591 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 diff --git a/third_party/golden/deborah_ufw/numeric_25.png b/third_party/golden/deborah_ufw/numeric_25.png deleted file mode 100644 index f0b0fd8f6d2afb725e21d3a47482be225561093e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2053 zcmbuAdpO%!8pk6NQdL43m(ezeTcuH#=|&Mj40%e>R*RxbT*i}LkgBS?G1Dj}DXokm z>6o@wXOcE?r!KWLOxCTsQjG+I{#sJO)cv-<>9hOSZg=N-_B_uy?>Wyo@AIC^_x+qa zf3nv;HA6KB1hS9hO*{$Op5H4%1#G!NJT_>QXeYhgA-sO0ci;d~X29~(+~?X8nFDPpJV%@cTpM7XvtL>G0qg9oXCPN@}G)Bi%4?I>2O)X+bB zbd$L}KkCw381bcg&aM-H5AnJ3!OO6~z!4~itW~>4+CXrzFsLO0=8r_&Lm>%nsH_|U z1fC61gDUC#`$RXVD#MM+m0xv=lbmVh?Wc0}Ddbjlbpji(JIFBeJ!K_2`EahCGM&AxsPDx8E$S^4tvHN0%0kbhb z)aJG}U+E#2E7`U8Z-~?PpM758%I1l{Dad^{gKJeQhOF-k@AT-jB@*gssNP`46 zn_bC4zi9^Ey|bD&JAh?AjH~1reXDirp5hXGZ*D_kDXmn1@dz7PCL)>+@xHLyX_ArYZ(5rDO*2dDL-_tHD0)uJw(b?G}*$^D48k?dhN1wKY7)h`RJmqk}iFa6OdoDeyMIYg^^JJJ+XNe&O}w z(2#2xI!~X1_C3Whn}7yWA7Di4CpgHM64}BN0kWn^rs@8?Bs4?bwu>miIr%IFRBr6L?WCKItWs2_3 z(fsuM5WlkGfkQHiwg@V(Tv@S z-GZxZd|tzKBqSKiYE3_Z-$Hs5!^FL5cs+`b{K14C0+=oo2EhK1p zGiIA(?D6ri7sUV&TRH%A*~ZJ=u0ILIjuxCpK=;u5)@CNPtdXFDRH`NX#+V7gADapj zcZaJ%O_6?J96F=bVt#^I19UMS9Xb2BUhvFlj;~F{}RK=;cs@ zc@(E>JU-L{x(;jepS-?EU;aEWuy<~bDvw5K&!gG{N}?5y`61l8H;S3Z$3JNJS{2 zNZ?aoTLh#qr+#pSEs;{#qL`XReE*f>cj_;i`3^&Vavw)bL%`^feB1_b_NP0bET$H5 z6ORThppJw5&08!M3zdv2|18_+?cg?|Y%u~nU)ojIqUh2qVZxZS4#c!K=q-^*{4$@h z(0MhBz>^q(>DUv%>cu>4;h zT^^EpJHx^ppRe##kSOYH>>o`2C(8aAG4pwN2lGMP;ko7GD|R{7BD)psewFNN-ov*U z-=4=E0j08arNjx-L7(pf`zpXpZ zs;C2^5NoivVz;H-E0DkCfSgKfLThi`s5@g`oVS`ZNxPV_pwYEjVfitOs^?xOTQx#1 zN>uVZx^`ddIDSna?zC2r&G)CIr|VL=tG2e77Ad(z6#WE8>sD0UCFQX4&kwE!5 z?wKJ!4VttjgzFyuB0@Q#zX^otHriI~nBQ&kVa5p0+|E!4F!>pR@8|AfL}MB4n(2-= zG`pG(-HNw}Ab*kHUCF|g&si}w!FSu}rC?J>=8`z9`1Wkv>Xh_|3>xF^7og)d&fT~p zQ(hl*C@dpa4f$d0<)!2*i#=0cug3B=*-&&iP xy>P5pfbrY$JY=B>)7Ng(+xy49$bacd$*S~HRIQuw5%4RAkUYsmp8KD3{sCJRg;4+i diff --git a/third_party/golden/flutter_logo.png b/third_party/golden/flutter_logo.png deleted file mode 100644 index 249a4a90605280ffa2c994c758019088fa494d77..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2763 zcmaKuk3UoUAIHyFGr!h0Q(@Szi%__vGpS~6wn-{UD%C=XB8%iE+L#=RVa4qh`6k_) zLQ?66Zg;nh=2wd-O5qTxo23*AeUJMG-1B&R-k)<`=kAR925zffYu#~tKn*GPv1SbP6 zv8{4u5x?tH%+KtXjL_ye2_v$~;6I5z)M-h*Si>KEh0+be{Q z`ttR!Y*wsxk)ZJ+(n5(tE-1@kk$B{K9>tH2TTXx;LaH6;QfD~MO5z{`dk~q1TTOt{ zAk{83%^Ut`CBe$UX&!}5$5{{{CA200O>>6x%q3VEILM{2X}I4AkQiDMi-wtSp0y+? z8yw_O&eL$#1Sk_)vmOnD@Dpc=q+}IpV&%BB$1RL zA>l<*Gf9XXd?;f%`;z;)ltP-^m5w(i@a_;a5P{c4&|nF?NrEPiz+=+#s5JQ}4n^OW z{6@yYKw#5C$+(5+w7cF29dQ)P z1ZCQh?kv?#b-&#Nov*690EoK$h&ZKN-qHF5m(-p+ z-ZA}z%;K_sz`KHSfl9@#5U5c}-$+g*hI+SsISAxxeQwg{t!9}l3Pq)Wkn%H|nR&{&G?oWl&q!sA&>iE#BPPqNsRBKDq(%K-ri3t;jg zRlqh8z?J~B`S{FYj{yL!kD8{6vIbiB`jOMjRv&uK4~4-W!3McSXH}zy7P{L97U?OAO~t zs`JhD6i?!SCNc0epRdfnWFde+AcF-Y^BMh`c8C!~76($4Z}|*Z(=KI1ki}sXLtVQ2R8WvdXeSK-u)P)??iS3XB;Dsg17PbpKN?Zq=dvi@@O8%IIpH ze9^W0BSS0X1#s8FY^M7=pP(IMlujo*K3V*-fU_94zu@zgB}10HLSx3BM<~38KlLzw zGlK}f4IaH}OYH?~WGpthS%f*kHE=KgL8o%I`Er zmfA*M=3VI1Y|D~@n3Fd;F51tw8DV(Oz68tuT0RtaaQ|5l1G#rz)TJIZNw!y=J$v+~ zxS?@i@>%%$f%3@Nkz_F1=>2A4dCcbY^b$h@!OCq)t3OiHjfeN*d2TiK#9Q7bz|B=n^|M|s^rHLAJu<+A6;0K$T4l$lqQX=%xnynWA}>^){YgdIj*`s{QIlMgWqHq-P8ThZvTauIR)X&bP{I%y5c2Eh8T+i}xOGGtIib&W1gljV5M$UOKwBH?{dlJ$B@V z#q8m*DTPi(jUmIB$20KDW)O~u+I}nh;tvxq=z3o8lK`i;WrX%sKaO|j;rXa;-=Axf z^nav&+87$+f#;63uD>G0Y-f61{$GaW&{MA$QHP_}dM52*vnliT7z+-MVRp_=Esy(h z=we;5tgtt4;&W7Isl}S+?2A!$Zn>2qoJ+b++O--AHBZmV{9pUG5me}Y523%wss64( zCht*Dn_sMt`(4w|ZHxu}twyq21t>!asi&GB3x{lD`jhnScD@L%JbwL1spX5#iLk0f z`=Kkh!>KRsNiTP?d29;KlGGSYZj()ruWpfhSgPQ{SNn2$)1MXARd48)bOagwS-3MJ zTgoDLx+rde_g-Ex$wa|kUfUBd+!zQCIWz6B;885sa;#3hGfkdn zvi^h;U*{$a&+zS6i9NdCC5@k3NK>dMfTrLRgUZjJ&!q03(t_7i`5pLNoo`Lb{OUKJ zUEjathb8ZO=M3~ow4-0Vi7Sv__A}butnjZ!iVsI<=eu$uV4PBY^?}f5EtT58pm~#p zqVBe*sDF}r-|a_i$3!Zsb0Q^hnY>~{?RGSL9rDoN+ER$LN_!KB4_h^5SdOypa+J^Cb67fIDrSyL>4D76iq}>(m(h?^|EzO zQ-FY%-~y}4+t+S??CaQiKjqIi$qpIgDudPX`MOta+SRZA?Y&c2X~tP|N>7;Ee{$O# b(>?ux8W@M0l~nW*1V{k^H-J;c7N-3l2=~9n diff --git a/third_party/golden/noto-emoji/emoji_u1f600.png b/third_party/golden/noto-emoji/emoji_u1f600.png deleted file mode 100644 index 395b86616a2d9ac79343e90556c708d3d4bc77be..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9294 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 diff --git a/third_party/golden/simple/dash_path.png b/third_party/golden/simple/dash_path.png deleted file mode 100644 index 79c855ce509992e9e752557bdb38b7a6ec61bcbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 794 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q`ho-U3d6?5L+bs|i}-@eH2c~^X2^xbSDM};;2uCmNC zc2wYCX>uTjsQK-;YxB9dhi|5EG9C1@Vi6`%9|y~!m2 z4T!gR&Og6huh+$Y{6)IO78BC%FDbkGRXc7z(8o7C+Y_2l0tPLdP`DK@tzT}xoqO|p z?agg(KmXd6dwSpd(|_yA`>XYe&y(&HZ|j%wrm;~rRmWzw9)D>qZ+rN>b@|cx<)>I0 z6Vzp!IGG$31Xze69`3*C`MvJmdr9k;AEuM$r45t+9Wp*=^Zm^Bll71O0vTQVw`&69 zac&8R8d7pW2?peJ1eRzCwtjj3+nVLSub;F2zwYy8*C^a3{NQcO_j#hNW9q~J1fH&b JF6*2UngAXN{4oFk diff --git a/third_party/golden/simple/dash_zero.png b/third_party/golden/simple/dash_zero.png deleted file mode 100644 index 65f09b1ccfb2651847388280262e9104f0962dfe..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 775 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q{$o-U3d6?5L+y_mb$ON8yg=J4;fJDAjEXK)=5WhqZ6chKtaR*>Dn6683C z&x3Vli39si{nr`ct5esuh^l=5EhlJYtiS)*nU4-EK*Pxg2kw7;`}OPB(pR1bBzCRq z{{8#+j(z+3u4b8fovn9U$z*(CTkf0hzb$0=7GM2SzQyZ<_|hqlo<3FWTJ+g zm*%QfQn@kq8-Iv|tq!%ZwLN|=7AWEh)NOw+pY>tzid9;hbh=NU zKFxpiV&>qR*Jh=2Lp?$);6O*-efW;YyQ*d1Zu;E>SJU?AOoSg~w(?3Y^m zuOat1I5rn%eJYJLKlvl~_OZ0hol`E|Hod*)jN4_Ci9u3t^OfF9{{Q&VuxnAru64?X z^u+d9e)ZUPJ2xd#OpuAG*{1mb17jm26B9EF3mXT=wzqIKc%qfk!|6i`F0JtscH`hMzE~O?6C3L~@A>4jiF@OYr)~cEa+YxG8K-Hfg@uKJr=J#0`WWn0 zXd_p@b6p_E{ki83{jYcu4)kd{)TkdK%c{bsH5gR;UUr%HeB<3b`xx!>pCfd{(!WQu zwA{3=U6#-ze#+L~-u?dfboL{9V)0J*zZVu43%dsLtTS0&Fz2_T9OFZ83%UM{aqE+J y#`IO~i&dYizfkA&j=g*5zS+Bv{4@g6`Tnc?rrvXt^NvI~fViHnelF{r5}E*%OC+%X diff --git a/third_party/golden/simple/ellipse.png b/third_party/golden/simple/ellipse.png deleted file mode 100644 index e1a37159cf6f416f5247e6b04980cef2349a56f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3847 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 C(j>9~ diff --git a/third_party/golden/simple/empty_defs.png b/third_party/golden/simple/empty_defs.png deleted file mode 100644 index becf0886eeca7ad80575fda67a1fa37b48020b88..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 492 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>pxiW17srr_Id3mJ@-`SS95~Qeub$z^Ei|K9O-1GQV?RfGS!SRvJmA6X$Ghg2 xm$JNh6(h@FZOp;a>|iiT;12^l!3mN&(67cP$`bZfiT^Q(>*?y}vd$@?2>`(fV^#nF diff --git a/third_party/golden/simple/empty_group.png b/third_party/golden/simple/empty_group.png deleted file mode 100644 index a99844327c1bfac8f198f09e248975e2ffc2e37a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4013 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 diff --git a/third_party/golden/simple/equation.png b/third_party/golden/simple/equation.png deleted file mode 100644 index 51a8171dcd00ea9559e87394c6b88139b030234d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3060 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 C7uoLs diff --git a/third_party/golden/simple/fill-rule-inherit.png b/third_party/golden/simple/fill-rule-inherit.png deleted file mode 100644 index 7755de05be13f5f8d7a4994941b3a14a7c171d6a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5300 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 diff --git a/third_party/golden/simple/group_composite_opacity.png b/third_party/golden/simple/group_composite_opacity.png deleted file mode 100644 index afc9f608ea21aacb280011cf76c324e610f0ee89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6635 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 diff --git a/third_party/golden/simple/group_fill_opacity.png b/third_party/golden/simple/group_fill_opacity.png deleted file mode 100644 index db3b4438ea100b9d90e08fe5916fe47eb7b344c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5155 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 Q^g$n>rlhS{C2tk+FAL$6wg3PC diff --git a/third_party/golden/simple/group_in_defs.png b/third_party/golden/simple/group_in_defs.png deleted file mode 100644 index 6a448570ed257ead006953f91be6d1918ad1c228..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1717 zcmeHI`%}_c6h~JO-{vT$Yd~(Rl$wRws;epaWZTlovNTOd`4$n85^5zSTAQi))?6Q$ zR+y%^MyqC)r75oRm>u6z5a~imKG5==?zh>0V1L*j_s+TZGk4CNIp=)t=iGZU_+Ws6 zuB9#n0x`e``W^zY=j(*Sz_tDumkojj{ZPO@2v=nF0o-WO_u&u2!I1=yNrOOOQFve6 z;l#43H}crhK&xNW?X>Bqc&NWwvK{0I;l8G?&h(2K^!M54G7&Io$UQDY<6+ro28J*;nDed9wYJ; z08l02vc;jrXTMV^06;DYH}ymK<=!Ws0f1Pm<3%I{UmX+8kBby8FQTcEvGMV{Zc5Rn zwJ7i;TN!HF<%WEl0GOxIMMxB?o=Z`!UMUc#jW1d4XDja}!8Bt_ZgR*6FS08HAFHl{ zP{R3jMHS7lslc^zd8@0JAF3|(5=YK8^TZWiywI0HHa}(zGRg}{AF_sb7c@)O^n+^#1Je10|dx zXM@~2!F$$gsdVSwtRKiFV|{&n1D!9Rw^{=o`>@5Xf)h06_P)4D;@cE|y?eE_T@F1P zz7J%2?R$E+7STmblKL5;=%;??2-`4?8PaiR2(*{t5={L#t>{>8%E#Lx(ys2BA|tY%#IEE>$WJtgvlor9h60y#?qbV$bIg&7pqk#%04$u!>KNXaom?X7z^z%}7F zZpr4?+|Uri#AuqhI{YbDmC`z+-vHC@sO(Dkm@%twII+Au%6Cn9@f z@lo@au|sQbe3TA39^$F#Y0!pBHKhjnz6= zFzj7Twp?T6s#Fw;q{v%S`6YhQH4D_dthBtmm3uQ9>c8w6$X3R?T6K?nvbQqSMkwrd zj~Q_mR+%}f+$u~9ro~!1jNT~X)G(LlNP_H^V*9?t*OR@O>-oo(5ytHn_`Dc1irw1T zPu^9S@T6@tC+#5nu!;4OMq^R&)X70M3 z$W1a8&wEy!$YfF(k@Owr{T}9a;`vczoS7eyDlySMQEn6OfecDWNU(J({nUU-?^h?5 zT}mJTHbxT%`kkxo`*tGzi%8WRGG~3IxCTFjPN$1%Yq82Q=9d*lfw<+#lSU6QwOvNX zK*{l}wFguQ-QK66+ZG>}l~Rp*7bJAgL4i*SRl=58OPcCGGigj&#W+6i71*nobkU}J w2&z-tV9uIRP<g^<9Gv^}%hvA-_F+Y&*BaenC>w4Lz@ z<03PTB$Fxp-NiP2moHF~r84vKr^oDZ2`8{I@)TB*cwI71S)3W<8kYsqRsgDrhu)5t zweD=)`$li!L5kXyMM@n{K8weEC=FjwkvGe#Bm;R z!{!yH=jIc7%1S$<*}B=y8S9O2r|IS58#Wgr4{4m|;|wjS+}G!=3;NCktR`a_kaR&s ztij^!Ff0C<3+A4Y$n+4%Eqo_}w*4b~&z2nkLujTD-Er-h6M9P`!Z8BNf<&r-q;2k) z7!O)R7~HYaX)iSGgnExgu|s#Zm#CGI^6GvI3$&tg6VvxW5bvW5g2Ft|ZLI;rnFIAH zvdW{vf|sJw1zu5OXu@gkHCIvA^}zpMq=7=^rFyD(0m*X)E(D z7t9PGXTSQqOmpA9x{Dlt(sFR&dtERe@#I1j+H=fTk(0?yD(w{MGj)lKZ?W-3khT0@XgryzFd(8JuMmy$ z*H-$`T2q**BPzj$+17OXY}}8>5vfXgt>P=$26XU z1PqkPjFVR#yomQA2FwstA1sU9js*P5zLR8n)F$|;pjcENwba<;?BC@T|HW@Zdn1R; zVzF{Y#I;8EEb)NQ>L9G2%nL9qmsrw?{^+*)sGqaPbZ9Dp zWS5{b)4oFjAv`VoAd;yabFDKyTL<7i+yf9)aZ#!0+6)91RZQW}TBc;X=-z98W1l#^ zwzf9#vhe8WVU?JWqt~rfDjf9d#Yr0S32?bIVX^xEpH2UBs&Dd@3&9EcVbTN8KLJK` LIgYP(3Zwo75)->S diff --git a/third_party/golden/simple/group_opacity.png b/third_party/golden/simple/group_opacity.png deleted file mode 100644 index a48b9668a583108db1e68deb171ea8fa32396f39..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3772 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 CYBse1 diff --git a/third_party/golden/simple/group_opacity_transform.png b/third_party/golden/simple/group_opacity_transform.png deleted file mode 100644 index 49776a056292c2f5e6bd8954a2d2e1e918676b80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 749 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q|-o-U3d6?5L+(e+nOlxTg}&Ku04y<#PMFmoEuSJSua@2znTUAXf2m8*PB zYi`fEGNC-JDz@r~VY$)$P@rjez@Ou14S4FK`WrUxl59)Nuw^>-D*QF0K^jw|gMz@F zZE^*jhaUzkzx?vi;7QN#vJ0#-F~kE`EZf7IUIDvHAYM z-RF_z3Ds+_OG{(J+Yc`U%B7e!hSc7F7^OG;>%V{Zs<@0FmX>p*74kCKyDA89uz)>6 zh)OV-f2Xdd=E~2SJlkf$?2oT+USuh{5BG87BJihSvTmEG~HhH z>vok(C@_llzkl~`*EMU2t--Gu@uVA|R7mJm@%_h5CcdA`7Xni0>FVdQ&MBb@06z}x AQUCw| diff --git a/third_party/golden/simple/hidden.png b/third_party/golden/simple/hidden.png deleted file mode 100644 index f0268065203142e822275f338f194d7799cc0e16..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1960 zcmeHI`Crlp7$%)kmZs%qmY_>#C@LOh%|b{_zyq2U774mM(lVs!H1W!6UYOxQUIkfS z!fa|2t>%GSf~Gbo@<5AH^ZK^b%!542(f_dhw)gYA&+~cTAK&-$d7i9;B)q=fRy_y= zqE94v`fK#@mtL!@;i{w6JdLc0@yB~Ws%2)NX80<`gLrtYrjpi%WC9!{@F| zzQjaa``N60hAiDM=3z#vhHWUuRd771<$hS0Z@1nlsL63dqgZAw`!I0vkdaP?MEd82 zJ&0^XHzxChS!|}U_j_CaX8_aS%uIUv+|_Nep{{3?k>?ZB>V5KE$t{C~ZHm{k#wpP$ z@@d|9?XB0-YMsF#mH+%YNNWxja`Auss~33FTS>NHU)I0VcX!E-S)XSVnbh=FL~vb6 zn`8M4H`n+SRVPJ<;M`(v55%mX7tuv;=g;YjcLV7t4kN%V)m>{McKd~( zl)T{I6|R3`jrdX-rkO&eueb&^|Zs?7{E5rKsm-T2PMvQq*is3pt#_0YmbEC zthJ-Ey-3=T%5^{=yJslF94Oc!7!9N71)h%bE#(&(zzg9?j+7F;1>`7H0TM8u5y^9T zb3+*d_}1MOtr-F#|0?{P#RBp>TNH;*rqa0LPZTOO-ysk&dQWK`H&sYy5m_Tfk#e4b zQt*>jJ#JKoHjemYry;W8=W-IRZAT0jbm@9co3y=Mv;- zljVFZpp%vEG;g}QfPzoA1AkO zaUYk3Egm_TKrswfMllRJ^nO~3{a}dw*7?a_b=ae5$9J2?Bd8WD4de}tlJ7fFHM$$L z*8F$KslzfF?Vm?NbWF|3OXHDgIl12TRD~h-N6pi{yz#aL%%HCm=+crHM~FMUn~xdA|Zy@x?sS)jYd}mb$%r8Xt51?DdPTv*j2yZ_y{xeE31FJh!&m2 zyNg6lLcLs^ElbCAVjego1W+x7-PS?w5PvSVKDCOnV59H}pgP-!?lqY4y9n zxk&JnS|G=uChsYAc}f1Pg=3(2xfbnJ`}L^qcA~1fu3;;(vvJz{q^yv2?q%?8VMvei z0eL_qz2inmHmZN4M^S} z*GsbG%$;R3`-Pia2ah}LOAD-eahWT4p7(hPNw4bVCfaC-Pdm=$x4$=qHOJx5ANNQ` oLRS`Z_YNPaX}>%2NlIDKZ}x3mzF$vdYSI=$JV5fS_6WZ44}C~ei2wiq diff --git a/third_party/golden/simple/href-fill.png b/third_party/golden/simple/href-fill.png deleted file mode 100644 index 713fb525fa67dcc4ab23ca4ac473a622fe11e246..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2021 zcmeHIYcLy#77lV1BbD3IUG<7ic55lE%@(bd(94jzWvj6sZDxQ?8w|-PJ0kc5p!1!*%s_zICy*#JgXNnglmY;| z$jHC|)YbZBk>d3Jv!An-Y~S2EBI-pfG1e&B;4Q|Upr36X+5p{t+#T&!ftrma)*+4F ze>N%_ap=+~T-eDPY_vT{K^Bo--OJvGC-0*DmYfKf*@zOE0BUdg1Bm~}U){i5sK~@@ zChL-F^Wxn${SUBS3AQ(#|46K6HGBQB=14W?tIkk&iU@lx_DE=#)g%cjyF zV@jQ3WK91Jv)Id7N})@LLzWS(AF{MQT-~+mmVV{z8DK;!dY%IgX*C0a|0nt#7al`B zujMKc%^dkhPPkGKd?{JA#NVQ;^6D)$ro;r^MAv9d*v?Ldq2Gl0!WEK_7jqzYC-(Lj zrwbwEe^y){jiG4VKFVa;%o@#J+4=;lho+ypIB*V8PWG6n4civq@NvgkfkSH3^+RMV z>#jtr#`_U@6YTt~HI2A zYV9+on^ZNj74y`;pLkp2+SrDZC>Is`)7TwanBs6>MxieYo_AQahze645Y^f#j)5?3>8JV}p+>7!pBKAb~tiF@8qLO!) z(~=|d*cJidS1gX(a5feW<*zi!N0i7e>4jB08hm(9%3i5-5J>sw6d|7{+r)mYdNT=#z}Q$y3lLa4ScEqT}s+67e}nZma%U0i7DK9=JFtYW{t<#dygvzL_4 zx0)IFE)@&xDbwUL-A~rJUe|Ha@KZb1M3<4)lCgEk%`}jyqs2kDf>K7VxcUe0^}aWF zT33oUXCI`3(Sx>_#)AiM9LJMV&F@B2d{i;m_;OgEO%M)IxYoCds0rZam%a2T_Lz2P z5Q8u{E(D%Z^rZd`_M0^!^!$ZU2%kUHl#t}Q>(G1KqQ}AB?8#=M4(y`K{LsteVQ|Z< zcR}72u3|O97j~_{V{yK9jFYh>PgPG(pm=&oxi6{;hG6PKWbQktzK@#sjjADBfCn`*BSCO~oO!ov0ubkv5wDbV< z*`+JY0`cgm;jVw|ayIt{_hM!wiVa;fq`XcUc>RFWh(RmUk+Y4YA_va-?(ONe9Z_p{ znbh5eZntn*z-52m)NSJVdm?fsYHIHC^H-ShM7xs<1ZR#)0kS7vVGcrt3(LF$v0O$a zFs<=S_@Y5+<>7__M078|*Hz$BVV+1oMoaA@B-t~xpO_MCp=I*)#N5AjtTJn2I8qD& zikyr;y%65ld5|$~o@Y{g{0Iq^c5fs~bLZV1tSL3NYSX+TH>om=9eyaG zEb=Q{MMqF&d|jo~l@-QjmH4;@Lvnl&>N8^RfvZ%pddF_{-GLlTStR2F&m?4gqbt7j v!3OnX+Ms`m71#{YJ!A|tHu^6Vv5by+Y{kaS3Xq0Z4L}Bk1$Le||I@z#FeSB% diff --git a/third_party/golden/simple/image.png b/third_party/golden/simple/image.png deleted file mode 100644 index 116280a365107c13fa007f4f86da98e8cdb55d4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 695 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q`?PZ!6KiaBrZZtQ9?5OKJ8*69EL(=)>gcKD{8Ibpdp;liU&8!9ZG&H2p# zu%=-HG?PQxSPQn_9 zFq1?j4@-9$J-^kNyykBG_N(8Y2l@zbFf}R=BA(Yy2>qs6As`I$HwQtY%;ebn|LIQ^ zSvJj1mQdO`7pN!2{P@(=*QdAdu2Y{|dgw;mfOwu@1d$k+#G3bz_e`qjw2tJY{R}|h M>FVdQ&MBb@0KGAj(f|Me diff --git a/third_party/golden/simple/image_def.png b/third_party/golden/simple/image_def.png deleted file mode 100644 index 8547af94288ed44407cc3a2197f83f4338fc4bd0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1193 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>AUD|4#WAE}&fD8}{cd|nv|Zddd4|J;Q-9-CJ^mc;{2q9gWzzPXT(gZYqueix zED=0+xTfq@nnc?|2KTMc?=kqybWjlBU}0*cFV*yPr}+oT!v;OC|JK>BE8l(h;`P_1 zfA`kxU6y&Q^!7IQ>)l5my?FigyWdn{klPG?3T8{RHBZdkeYfxR^5x45|Ni+?^Ci0{ zI{y8Yh^*nU>?)$%AnY?c0ELVk-?=8PQdi3bU{qME*>sUXTzH*p$ zdi(Z(T3)g4qwT+sTh6LgSbcR>No@It+ufNJwY9qX`uflB9jiC`>2UAA*sA$qckkVs z7Qer4>blqGHk$r>@bl-+J9qEStyyHs)4V*wAf2f(;gfQh=F=zat^EA_?CxflKmGa@ zB_}86S65)o4t6sz9%lTpJz>D3{@>o?{`bwZGykjo{`>E+>8kZlW$bp8Hi6?QcQvGc%>?az}6qJ^19kqnG8L_YrHu9#?I?IRzBPs&)%s@7i=Thi~1@JMSc) zZ;k$u1_|TKChW&QfzkvpexCxPROa?0;cKr;GiN<}Fl%nr6YJ2){7?M1-Ohdad*7Y= z_xsoH-Lt3X^}hGVzZ&q|-?e@Is=8$T>G}B!e@(yo_3PLEAC>3rCj707_p*>>{-`_g-KTE7pN36TB_7!`){NqxQ{mfdf3h_^`?9W+| zymGyJ?b%n^mh5?#6oD!8tU>e6#rKkIjoy~+Uc6p<^}h2f3s=WoPriC*UXmr)x0@w4 kK8Tq!5IGYRwLjSXt3LI-U1J;qEN&P)UHx3vIVCg!0GRd3Y5)KL diff --git a/third_party/golden/simple/image_transform_before_translate.png b/third_party/golden/simple/image_transform_before_translate.png deleted file mode 100644 index d1517c05ddaa61f2ed3b9daf6025e23a62b73839..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 675 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_mZyPZ!6KiaBquD&{!_GPnfVIfjRn*k;JQjN5Qma$gQ(XF50k?OEABPBuT8 zBigfbX6m21p0l%e*Vmt&w_(=#+oj)F{@pky$FSZ?W)E9&Vn}3`}PX44$rjF6*2U FngAK6j^6+P diff --git a/third_party/golden/simple/implicit_fill_with_opacity.png b/third_party/golden/simple/implicit_fill_with_opacity.png deleted file mode 100644 index e9a11e8f9486a8d2f3bb5612d6f9cb3557162ade..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 699 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q{7PZ!6KiaBqupY}cMz~FlEiu?zLwUz}M*98}CWXRuv}P1{i8$C|Gb zpZV;=w|^V?9{3->$^5`xn1iL!L14HNEuY^o_J6D0-(UK7rfu?MzV^o!bH9H*{pR(S zdrM(k7k9pFUYtA9LQB{7)NIA4+@s@%CH23Co|Ke#4p5 ip)EF?Lkqv(TH;Lv1-)v1@0|!tfDE3lelF{r5}E)jzOJl+Z{3A;`8q3&*$;^3qI%ZIOjah<9vCZ=kuKNJTHpJ85ae49eF7! zDFruIlqXQLeq^vLP}X?YmH^c*oTrPkRBiu0KG2ZCIlEl|1BnO@AxlZgquo$W7vhTq z69Z>;`P%QqMx4J4%5)TEDW$4^s9LC?8XoOBqM9wu&E@76Z49h@ENZ01DE4`pC|4OD zqGW*dv4&vNET@j6m)x_Wy~^aS7lcle2o7NmBBJA5v(4a_g_~3PlH%8~L?Y2#s((d} zp(GWKkpUTlWjvI@k6_A3C)mGkBc*;KNy&r6=bF)yP37y9(ygOXeix(g>jjoQm&L9q zl;R#2&zkREC=_7o{CG$ASjt?(-W( z`1tm(C25t!mZ{{QruGWB*;8q%b~4zmA?(5H%bC@|fx%hGGk|h8*XJji1K;Aya-yIe z2T~J5r=8MocB`wfs^%=wzSi2*5B7#u<3_)KpO`_NeekxJaK6sBy7%%lcfc}_;Rfh7 ze#@zccdZ0E3}BeEpE~RW>Z*|A9qBq>@4C;ROZToa3rqGvHK>L(%O3Qqqo?r$2Yct7 zHZ=ol8bq?V8Lhs7wAO_K%!luZbaeG{^Q%5hl$+(5H8!@Iz#+e+_&+>r70W<9lNQfM za*#p(8qo4ufe;TMzY;Yq;Ta>}2#BPjFg=?73(`IfDt9gjU07g9V8TN!5W+FXdjGdD zv+Bar3U7+SQGj^3QZDH6-tr5ztYuBJ(;uu3+Z*B}%p``+g&Gb|w6jJyk5Lo01exFW zyGncTxiI}og0;!r7;M!?$_ei1y-h43`27k2zzN|6O|mAjn}H6!lO8;^IF17iQRNv|HTU_S-nOg?d@>L%62AHxe!FuX`MkMR{Ez8xIpKqYYrT{cz%9dk z)3(Lgj(O{m3->$2Ee}LI;7`@~R;O+Ew@#3>6jg#9+i9IAj5cTbzM#i~IuPte`|L>0 zqG<+S*^qoHs0$ZRcO%>jEf?HMVRdz{`%wJC96`;)uY&L7aYzs4J0d5-^81h7-tZ5u z^VTKvcf5z)AA#kfq^*jRZ)^`v0y8T2Xmt`b8f=w28=7WEaC2MMm0pdflB1)8V_=!g z_`r)=U!V$=j%}=?XHMHs7tl%N2p3T|djHI#>3N!~_Oh*N&3jJzPF^pT9-7 zc~5&+qfpNL$MYck>vc$!^saU!Y=6kcp*0vnjUDw#c4#;z&SZJvmetRR_3pfr#@i)< z4TqI&6MJy`N1QZM8Bb_*1=M?D-#M*=^Oc1x*^QZB>~k;G+ba(@GHVVPmYT?Vz3air6{i8Wh~gC>=KKNZjcO969eAV)m;w7 zH&rF4)Ogfz3XgX7RWgqx7R?$ll-?=f__0UK_h~aAk1qqOav}pXAmzm5Q4H|P05-qj z2f{*HygW~Dg^w(DiN)fEDY@yi$Qp~}?_-XItpn3218bYS==lsTx*1Jd$<*s6Mql+g zMQA@?f_N=T{3}K16->immLuWX?0da9k0NuIKPk*~8iG02fd0M6%RaVIf3c~o;c(sz% zGF@lTb%v>%1?d$kA698e15=0Lh+K(tj4C zZno$AY(uF(Wl57HmHwx|P43ixL?poT|L>v7|2zJdR%=i*cYgG1UPu`baZ0%zKZB}u HzI6NFKJe#r diff --git a/third_party/golden/simple/linear_gradient.png b/third_party/golden/simple/linear_gradient.png deleted file mode 100644 index 2df89ef0c4295c366898623bf75a3b4982492ede..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1838 zcma)7Yfuwc6b|bGF@h#a>f$R)gb|5a7f?~uBs2kH9V@64N+VFi_y9!27gjTpC>U@d zkq$}=gBGlnhe1FzQ4kRfQB<0-m8w)wKoAr~kcR==dpC@K+stgvp4az%=j@%iDeKn- zI5K81Xf&FmBv2F#tO-7JJMe!oM3)PU&7R-@Kbr2rtXIH6_xMRR(!uXAJyK1h+5IIE z2{$I>ylE1~&Xh96=9YLZ?M|KGrA?VCa^hfcc}9%zS(4Yo-{uQ)46?Jjd+KW}$H$Hv3ba-XOpl)oqzq?J^_}%K>s@|`9_`OxJ zLls|E_WoME;qAWJEk&D-j6Qu*!b!eT!!Heu?(YfjzuRW0=)7HjO7l(b)r8UJ2P?xY zp$#Qo2j+wiKWRMCqqtLROnEZH=KR$`1ig<3ww>2;#!g=F09%#IsoSdy=D06DCs~Yo%s$g6@*@*ed zY>`(HGS!c{`hplm?m$2H}=c|D;+WUy*M^Ka)L48AesK$!^1_J z215ZXlRw$_9{c;&CS1!~Yz%qs!8EZkc_qwbV)7i&)V_u!*6A5&`~)L57tk4O@BNlJS9M} z{B0o44OT!UOm*M~;##tAs^D0m#=H>VvkF)G*8^TraW^)*c2f=uVHK?a5nBb*G{+;| zOn{ol!rR0Oi0WIg)W0FlmLGsTmKcZ`RH)FK>W>V_G7E+1Cy-7GdKbLG9I0FbR0MWI zbFQb_mkS;d*OGuB`#VcvCX;CrmZeczm#;rhgeLQbomnPjaGH5BkiR_SlvTccgC`}Q zgAm#+WHMZb(m}r00q9sO;^fQ0p0;p5Vw-Dci*f%v>wbu-4X%JnBGQX#C zfi#wJyR)vfYMvHIKMrPMu1Ho~Oz*0!G1p7|L1$L#YLOp@Zv8 z`_bU_nQ&_HCOwyd20KY3XCm_#SlB_h_Es6Bo4=?ZIxqBG1**CXyS0O6TV?$68Rk?yNsL|Fp*{=lJeowjPNegT GQ2h(ld;zHd diff --git a/third_party/golden/simple/linear_gradient_2.png b/third_party/golden/simple/linear_gradient_2.png deleted file mode 100644 index f89163f154c389b42c4d0fbe27b7ecd98650a0f1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 763 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q|3o-U3d6?5L+vCWeT6lr@{tX!5*l@ZfCi8Y1wX7lu<@XXB$-i@pgM%D$Z zLUwpo1+inyn9hA|_00D5ocx{FwV&;M5u-oj z;#ce2h2`H@AA9V-T;3z}>X$WH-v8@>A11-W&(-%D>-?0vuYR^;~Qd+%D#HU4&{ z^807o!f(M=_vNNfH#eRA^^5t|gXyHYon+7A)X;RWn&;=o-LGCP1G+hM>(%|gqe8cC z+ZP`neLLd!_qy}vx6Qk~qdsf>+O4tGOO2O2-}TL6+2-%HZF!%6o?m5kfB%EtFLEa; zY}Q>oe*Wv;_m26ATmL;`nRC6w>TRvp?!B>V)h6G2e&A%JP7Pb52Tn)ejlP2kJ8OP? nS39un_iyL)#T5!mGP?NG54) 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 diff --git a/third_party/golden/simple/linear_gradient_percentage_bounding_translate.png b/third_party/golden/simple/linear_gradient_percentage_bounding_translate.png deleted file mode 100644 index d1758ea3126d9e21b5588eebec8e83b6c0a572d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2046 zcmdUw`&W`{7RL?W;MJoDmZnMYijp->UQ$n*h_8qNR@yOV%1#|Eoje{)LoF{@hB=Cz zMC^=NR8k{lYDpK%icnAJ*kviBcErZiKur-Zly@Z@YW|9O*4ocr-~IjUwf6quSx@1f zFuJArdUF#K6H6w87GcaUzXpgj-go!cmK)Qm)CfA&q_!QWF$y4+%8Ue!CmW38nV6t% zGigDQ8CNIzdXpUfVwbN{@Xr23b(fUchHk$3_fE^ZR4f&Ybi`~rzB=IiL=Us8?p(b* zXzN@Le#NW2?|_%~6#8djl)bw`pFH6WW&N-=1R)snQaYGq?|{y5VG~oX2@$w4 zk$(jpL#R+siOZQiL`O`bZ=5cemj~aAi2ESLn{nZYr$JLGMlKZjyru-h_)v`-ciTaQ zR@KB_m)e?ff$H|4$p~k_`uaxX6IUY;BgDOTqZt9V=e=Xac`!nivZohk1e*$0%^tQ2 z!7y4Ey)RKFNbU%Y2LaXD8W07FE3)x4(fs2gc>8Tj)1Lf*P@vQAm_4~_1BWC)C&-(Q zO`lQ#o!AB|VateY4Fk16j>%kH!hz!9>R@GR;Q9x~`-c;MpqCwf_Rybq{q36%_n8y7*{a$PYs&T_>ox!>TRat9VXi;KCYqULl+U@sDE}NHyrdwd0ur z4^V8FD2Qz4+Hn&d(au-~f*s?)eNRM-9Whwc+;*vEzRNSVTheodY->=|W$<4u7r4(M5wpHMt zF6PW9onHNVG!D9uHt$w){dqf*h&6kyO@pjUu3v3O8O6Eph?qjgo?RYX1}#^<+J;AS z_T6=FB}dS;S2H^LvEUpWeqn73p}8^7!D!v+*`{}BRS&pW{YeKq6BDEna!Fgq02yE9 zf+(RmH&k;L((yI*6qn@tk1@=L*>;AyLH|}Tu82|HAykE5-6xxokOW(3N3@-~ctSDg zy!&=Z-uHS9r;i*4aniO}=LdetSn{)u4u_T>k-n*JU8N{i>&xvqNPnTLBuL^G9`b*M zQ>t9QxqIc3JFIRe!FzO3o+>x_IL&tcja8^hUeS$21w*Lq0i}~U_umc) zRmsb`sb2bLHYh%0ND!mu%Y?hs3J?7;oPlh7Ah}Cl7*>Nbx-MuEc-tIJ~$X(vZp3La$KH(xT zw^-g8u=q>0W@v8NGQV-?rz`e`HlKPeD8|bT5#fX|@5{F=vGU|vwzuA&m8G3-5jhFW zuUTGPGHA7bxE40+mdSbzE2$gH*xioY8IUu>>@t%#<`fOdb@5Zbt>DGB6~9y68yD+7 zg%UmWS6E3(Kb&FQ=Xvhiqu%>R{}?RRCcode!t>PE76d+3)CDkrh?-BwZzzi;-bFc= zUg|3EJdGNOTbLd%g~xpGZfW|Vvq!ro4#zK~D+b1OBkxdL?-=sI(YE?BhY}C{yX9TI z!Tqw2ee~{GNRWTkYGg?xJ>hK8xU5oSTVNR#?FFe{^fR)fHH3{@^=<`$+AVjpfX*ks zK74vQGpi&++M@G!F#JQ(cN&Lae^4jZMvJbozAv;h1QVQw;SQBz`XJa`@|EUL`ZGv} z7t*cX`sp>%1X4~g>bK(!R z$VKrIK+S#Au`4;6?=5m8dFrLn(F$EJNA^Vk>yP^hHN}MXZsR&1DQ_lxE`B~W(Cr5{ zJC#*jHe~xeFU(W9KT+P%sqx|qUHmntf&Vp}@F^b?4gNmHu`X2A&y_s*^B_(e5H$i}iVqc4ZeP6LXm2JL zeXafNTI}rNDP<|FKWS_k*j9O<**H?ow|eHZRp}5)DtQfbA_$7grKz?m+lRyLp80`O gl=()|qw=Yh8{>NxBE#v8#y{MI84^aTrN-p`7wwaYj{pDw diff --git a/third_party/golden/simple/linear_gradient_percentage_user_space_translate.png b/third_party/golden/simple/linear_gradient_percentage_user_space_translate.png deleted file mode 100644 index 888342afae3ecdf3e71903ed3f26ad0acffeca1e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2083 zcmdUwi&xUw7RMFwIZ5;@HI#_QPbO{16*{R|`3MBc%FNW%jB%=aC48V|YNq)}erly) zQ$s$w*Jwr)A5;ofqhde9$7pKT%1~3ZhniApx*9R>Z~lxqYn`+A{;a*vcb&b?Str+j zKg-g>*22KRz>>pe1R%Ek?`dX&tkoekWr#6M2w?db)b!vdkpP|G!wED)MylCy$iTp~ zo5S!9Oe&cfK5|a;1eY^rbN9G9ind+!Ldnsbey!23+#@JB#ap6^pIm0-E}`N?%5qaI zaKxG=WgBEk-tCe*?QP&%64ISPny~<{M#bIwquj}$4wqqIf<~>!nsL2|7YzTQ0he~` zd2-)%e>0S-I^`HEWm$daPC9Shd51;{cKw$EO6j*ol5ud_tY{fI^1`0Xip^#<-$FNW zQoeM|W!5+z^Tw+MeKv+m^GNFX&|_a0)Efy?SqCB}l9+AW%u(8yK>F(UGseFyy63J# z_jh?JH<)LPT8?p~ul^MqQ{|`I-1s-JL%?4*1k!RIofDxS>1Lau#nSg+;JEW#L+AWC zdshkx3kvin?sW);|6}WDCVkhOuo*yo3J zFTF_ZAn5_Tq9A#{kw$SAYUA}xn zLcHQuE3|0dq@GaDJ}ToY_$6R!pNXkdaCP{xjn(0_m|)PaQ0!4F%xh|2d_y_Xs4M}u zF@1>ki4m)jXH_OUUuLeF~?0Oe4b?^~g2?n-{E>}FCV;5J4pPMY2C7QWas zmq%E>|B{{btKxWS?(Vzex=!mV#unTE=Bx-3!sEL>itz33g-IV}?^s^#nxAbhmNRv9Ovu>CIiVf1)p-&}#w`7iB04$nUc zl+y6mjC(}>ob|Gy;Od{Buci0CjGSq|>)ETn6nz*+Yd!w3enq7z%BDTX{IF!yeai33 zT}{=F6y)&@_R~Sk^$&*$Q7dm0B5b?$wK1>!(5m-cEmvj^6DCKxeiyrC4Gq%q|2`P| zsdcw0?bd`}ysqsKsxkkBOK-V1eoL6I5r;3|)^N!r^tpz4%p|@QJ?MqEtmogC;0dI{ zAKUu;^Qjug*VuMjt;)YED9rExDn)qx#t@mXs-7SJ_M_EWm?*(-h}fmwiaJ6ftg=#g z+#hpCHG1#BJH(uA%f+MP_W>;7He#;V2zE6q&jZegUBl+Nh#wp!bhgjC z^aUG!x78bQhY73SXnoU6>9(6^zqloE?bD5L1-By#V(V8?JdGMJWo?VITR|Zx?WVKo zbM1>;AyN328+!9>w>Z-@v=3fMSu`SH_^KH%$S5q{6{~H*C~@ua4$Omygel^Vl$}0( zRd2>u4ST#Fy}+*fQK2J{Ro8}^6CiZh$MG5xFeLIkyGk^Q(LV@-&~~47`$+)5<>|w0 zb{#cchb60Q^-UfSS~1!~1lGp|vl*GcC@BGqOuIPOa3-kC@fh1qR#^=hyOMx#Ehgk5 zn~2&<0d(@u3KCE&pPD8Dv2yJ+8E}%nDkcKDy8dD^P+Qk|)*Bq*Uex8WAGJ)yWU))s zoiX|Bk|%d&Q6jf|t6?j$0H|u*%h2M3;$J|pgDlb-f^jl#5CogcBCbKw`H)808cwC0 zmrNA*N49+H@WOR!e2V=L{}}U0?}j#%bsm?z7#gy2va zM1$ZxvYdSoyj_+Z4Z)7G%*zmLE4xq)!4|0t(Z1ltapzbMvcvyY3@;FxirvY+LC8mM Nz+vuZ)c9~S{|_=CnXLc- diff --git a/third_party/golden/simple/linear_gradient_xlink.png b/third_party/golden/simple/linear_gradient_xlink.png deleted file mode 100644 index 729a425bf0b5402c22b36d0ce9dcfa544e147b75..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4748 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 SzX<*w15{PCl#3ND$^QeT)FHJ1 diff --git a/third_party/golden/simple/mask_with_gradient.png b/third_party/golden/simple/mask_with_gradient.png deleted file mode 100644 index ef9aef146598634b4257bb8d3a892e5464dcaf29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 648 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_mZ0PZ!6KiaBpD8}cz3@-R5g?*IJdLV#Q}!%VJUX<4B-HR z8jh3>1_mZ&PZ!6KiaBpDJMuOdFdR6*o4P<|4ljFc--J7oFIE@VB&;p%Gkm9i>(4dQ t=QU;S{dXOI2sb+zaIlOLBP0x3#A^lECIs$zC=N_M44$rjF6*2Ung9?Dk8uD1 diff --git a/third_party/golden/simple/mask_with_use2.png b/third_party/golden/simple/mask_with_use2.png deleted file mode 100644 index 7c840d0c4a0e9f476e9629817bd30656d56650da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1368 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_o9pPZ!6KiaBrZ#^%YG3$zAmeF)q0WzDJXKsg!5CWY9u{^gsyY@T1;a8&Qw z^=8AKCr`iL|7g{q|JV38L%>W21py8grbZf5b!Y7k_~_SvTEG9_zGpI#fsFhXsqi{lC~YHKeNe({z6U4lkBRXHTYwmMwBo z2$)JRdYXh9Oa9w0EZU=G9jGL*!V3|rr&xlX=IhQ_e@Sl&CySO4G_t2~Ex9z^_}PkW z%uAUXvsjoMcRH-9JyJBct2|y$V1iuc~^k%G{_0RB+Q_Ro#=KJ*UcJ z%>-5e-7|%6$tQRH<16ZpFJ*4Ld5S&gFYn>UR(EoLIwUL;Yb>d_Trgj+{FaiyjHSK` zvG*+gthpS!jguuUL)2rrIe+}?vi7x1jjOkEFS#wZM{nwjbI4?#bO@`N9J>A0ndv|a zO7+()nwq{hM&Cy`NTGti*JN;OA){t2D!@sZT$8ufAJIfV(*Yqtbw z+n&D3Qq(Rgmff1ZW0J$WE0qVW=GTff+AMgysMMyIm8mjddF$(vYgsIxTKKxJKkS*x z`NVUo_=Zn6cL|(e)Y3~jYFzpy`x|4}$88hz>$B!GC;wovym5wA^!P`Xq9)01t-fN8 zCo183Yb?$wPY{mXxZ{z$`iO{H{N)(W155Bw=+%M zkE`}I`xLzYE|hrYv2emdKI;Vst0Eg*7kpKVy diff --git a/third_party/golden/simple/nested_group.png b/third_party/golden/simple/nested_group.png deleted file mode 100644 index a99844327c1bfac8f198f09e248975e2ffc2e37a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4013 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 diff --git a/third_party/golden/simple/opacity_on_path.png b/third_party/golden/simple/opacity_on_path.png deleted file mode 100644 index 694216ddeed7c0c9fb955b806ba13be53a230170..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1443 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_oANPZ!6KiaBrZ>K03fOSC;SpR3c+$RzWCp;=X@Q^sVIbc@ zMS)2$puuW#ldSLTu*y$?H`7Z?VvU`)Z9Q&WoqfJ8<9l4~vE%*n^($9Rpa0vk&;MJ2SCC<$g;+P+$vnns|n8m;Mzjeey z^Y4Yo%7)rj29;J>eHuh zTR!H${wneCtnbyIKP65d;e0aT?wy|bZ_0D`%1yVPA8uQ3=XX%;RN_77Epg$0zeUfs z_?NkJP1V;||KGpAqtqxf>+7ypUthmmGi7$f^Uv3mZ=Mo)Jwa#s<5NG@w&%P*^z*_Q%PK8bdax96tXua@xv!VAH(X)w z?DOhhJO6~5T|W4A*H;ggOIy$WY^&W8)Au}6O4#H4x^-$FHUHdQw|=&Kh=9lXu+@KO zN97jR-Yxma^fL6ZXmJux+|q^?TdReN!B&Os2kG zQ5IbmNPIKB>ibMK_* zp+nWx(_u>rUogGAdGu)A{78HI{C_MljbCykj(L2$2sHk2|5|s&3Ge34dv`x1TVmBb z+icseRYE5cckIY0nt7~z_Js=8B969&ua0(~TvKxK^76^I9&tVi$XTWvypQMUqokn1 z5Y8tX&ZLFv$NLp~fBKSn^=9Pjz(4H{d}q^kU43zD*?)<)RnO0>Z-072;Dq9>HB;8| zGoDWiwf}1}H)8va`&A4kC1qyo=1iYnULActQNo|eufXeTJ}@D=yFZ?iy>Ug==VxWk zl5HQo9&g^f*YdEwfZOro_3cLU-+xnFz%SPmIA`8FUkPcZhr!2>KYslvspieiBtyHc zuMW4rubzLre|hDVH`<&nZ`&STJ{=Oa+HlhM_xAsJCbjb)-~al>F+rw>uVrL=*Y}0} oTmR5NA3f3rU#UP|LG_1~+xO?X91gKEU_r~^>FVdQ&MBb@04^z1pa1{> diff --git a/third_party/golden/simple/radial_gradient.png b/third_party/golden/simple/radial_gradient.png deleted file mode 100644 index 10f672dd09f0520371c9463762fde4ae8c3c5ea1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3267 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 D^k(2s diff --git a/third_party/golden/simple/radial_gradient_absolute_user_space_translate.png b/third_party/golden/simple/radial_gradient_absolute_user_space_translate.png deleted file mode 100644 index 58976fa5bc3b1e6432c1c037ab27b7d19d546892..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13507 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 bzXH-ScMKm}?Yz5I_5(CjbydogtU~_}Pxwh@ diff --git a/third_party/golden/simple/radial_gradient_percentage_bounding_translate.png b/third_party/golden/simple/radial_gradient_percentage_bounding_translate.png deleted file mode 100644 index d954b9d44a82bea4b1c44135d80cdb2794c5b615..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7056 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 HYux_<=Dtp4 diff --git a/third_party/golden/simple/radial_gradient_percentage_user_space_translate.png b/third_party/golden/simple/radial_gradient_percentage_user_space_translate.png deleted file mode 100644 index d41bcabc74f62ef0d66aa4b337eaa5b0c606c14a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13092 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 Aa{vGU diff --git a/third_party/golden/simple/radial_gradient_xlink.png b/third_party/golden/simple/radial_gradient_xlink.png deleted file mode 100644 index 10f672dd09f0520371c9463762fde4ae8c3c5ea1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3267 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 D^k(2s diff --git a/third_party/golden/simple/radial_ref_linear_gradient.png b/third_party/golden/simple/radial_ref_linear_gradient.png deleted file mode 100644 index d3e685d9343644b78424a18a5be27c6d4a731303..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7808 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 WrlW3$nf;}T4A4^7RV!1mj`%;^-BD=( diff --git a/third_party/golden/simple/rect_rrect.png b/third_party/golden/simple/rect_rrect.png deleted file mode 100644 index b125c3737f3936ef36523c517c604d3038d67385..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2594 zcmdT`XHXN^7KR|z5ZpCO2_i)x2r8%n#fKp@A;bViLZ||QbR`&8AW}pOh|&zwyF?M9 zK|nwSq$9m#K?sH(y5KG(AT3$^xASJ)d4JzGbMKiuXYQOc=R4n-6KiE*DlP^Q~{trH?0EJzKs`#c~iAljIz4Hmz1s8*B{A8V799S#8g>#nI;W0G$>RMhZe! zQw7^+AG#{XVka2^6@}AMr@;)YVRNUjY{8wzTzA|}oVO>Sk5pC?G-B|d3$+b%T6UjA zH#Dopvlve}dkqS2yLTseS`%A+yq>K0zW)CH5=j3=9Eb>@!_FQ$?xKKcKv3>Qn(+%f z0SGAx0*%F_AA+_1%Mp|og1^$>Vl`wEJ}g*(W+;JBx?Y%2`*Hf9Z44?2+sDGF6UnD+v{V1X*w>sci8Yvp4U)W1gk zX*&P+j)pNTa1F9aPPRGy)H*h++xkqe)7^bkZ%;PzRaL2H#K0s`sD3Zz_6$l;sc!ha z@V}7r&uUn8Y#M+@UHD7_`YZagRFLnxx{F!|g)!iy`NA)~y?tCA>B+P!x1>-g7^KjP z&%;v@ZCbrokERyyz}xX6dt9}9dNETrQZ&cNTT;Y}9v^ToPlwKME572->BAdjmREMu zYZ$H@@jQv*fQmYi_4WQ+&C^Pi&vm>n*x$@VzZ?SLoBUmU0E?T7UHQBy-!~sY4h}Hl zgy%*Z?+N*A7f4)4_#ztXf{2py=s+@b*;L?Mgd2OPzEV509&Sq2eslwJ#7m)Bv36rr zEpF6$P(RU+FQA z-c@!JXDwkzxbtX;vu^WJywun|>aPNjTH*q~kmtvyX=ti<^{1d$WrFlY#758Wka=$E zVaK(TDeBlHeC%Q1QQohwElbPF&*aX;sU+>4&z$dlH_<-=R`z>i&iy_Scaq#$I=8Z^ zSn~$C&XloXXo2F*{OL2z}YGacNo8D*K{o(e&_aCx9^?-B>-Wdwa_vw{xiF zIqR*aK8kC(?B|a=ck4zZo2a$kJ#3rb#6W&)Qo^N&%=xm3L-BS<1v{bEpkeQckyqEx zFQ!)d`(Z+Za!yb^YC8c_(kdaaB1EB}QAhSoE)syVSUk-O5yLt>u zY%Rn#nMUNNvPEo%R~fB$7>blKFXlNMF^(QN=#$hJmj5H`S%SP;9T8y?sfGJ!U5p_R z3g9fPNo-Ute~5=?~gC=`oesqrc@izE)0xkuoM6 zRUNo5sSiQjNf5@GsduQ?d$#a{9rc<)*1{FFqaks<1rk_o3Y+FPC{GDyolZ?Hk*z34 z(7~hiL#n)%yow$}Y_s{dcAbMj_?Aq!n9G52>vM8$7MDd+8>Y;aWh`ZWYZ+*Z$K zUvtM#4Oz;>ws|0;P@Jn^OL*&a8BrxKoA<0{V;?2*l50nFt}#h{5eX@)1lVHYjMfJu zjyK&~ALtzRXh>pMV=SnaF#_P122RrJS1_Tgk6*Drq96M?#?a-I3r#$^5@xyEXQ1IV z*BHmgs?U5zxPUvTnqw}1k~IGq-3C2&R4kC5SL7Vs7ca@A+%3Xv29-!)M;f`s3#c9v zL0oBQ6Jqg*87$^R*}ENinko_Z;qChiLHezQ5tp{_ezJ3VPDUZaGhz>vmwq8pOTS`5 zm+k2D^&MhzK0xU2!DG=vu#xMry9JiXyNmJ!Rurf6)Ugn#Dnz6KFOmad$vS;+JLh#X zEJjl1_?B`}!SS?Y@_>@Vwo@?s3VldNLnChXGS+=M@@p4iWSr}*Hs5!3XH!bId`BI< zy?SNUN>EhhB$1;M{Rs{%vP`B`+1a}Ic@~Ff2pn{G&P^OAa(F>fr<_$oxVo8RCCr4!_fINS@bKR1%fzBLFiaNwjHgW;4Dg^T(FWd97h z?gI#^n8Lp;XX!fDgU*$HOSr$txfC?Q+-2m{IQcX$cjMPxRH@a0$uiNE&AZG5Vn_)4 u+pgXT&9j7ey;IGFSS2*HzCIWl4)BrbR1{tI`Le&~@gYqtjA@20_x}c)Ew*(4 diff --git a/third_party/golden/simple/rect_rrect_no_ry.png b/third_party/golden/simple/rect_rrect_no_ry.png deleted file mode 100644 index aa991f9840437967323d6554aaa2681f78924729..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1731 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 AKmY&$ diff --git a/third_party/golden/simple/style_attr.png b/third_party/golden/simple/style_attr.png deleted file mode 100644 index b02af92ef29dfb62e440639c4864f11dbc7cbc19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1085 zcmc(f|4$Ql7{{+4F6@pB=(QvRRCZoJwm+KOE}>368$r4vt~hty}};K zv=fx15JXN!KvjF*?z;QqWxYr!IyK*3Y&ket3ZL54S#fo6#Bs#f{EYJ1mOS$Flj5?ej3VWOCJZ0YiRWXpPOSh1I{B@PPz$mq zq!OEAvz%r@fzy00Bjke;4DZ_w|G>b&*v$LVA&|<3Mips4C~w2pH)s(>ss-g5zV6T> zs zo{MRh72Oq949aCx}>wL*tO=6raZk z?||%`M_-VJUX<4B-HR z8jh3>kesKBV@SoEw|6(@9yVZbb+o!5ck7sQmGF9H{zW3|F6~ii5Hva#yY^A@fo3Tu zDQ2Jvq=Sa*yYJ*Z-}!!X`hlvx zsi#xFHJQ$Netv%J!!u#`U-L3KDhRM(A?`g}buxdQ&WA7e&%Igy{nuZ{8fWYZv1!I8 sw(W66U6SCBS088WB|RKKIv&KFVdQ&MBb@0NrhFa{vGU diff --git a/third_party/golden/simple/text_2.png b/third_party/golden/simple/text_2.png deleted file mode 100644 index 081e8ed3434a8ca846141b7af37d775c6abbfdb5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 892 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_ov|PZ!6KiaBrZ9?Xgfm0|mk@6yv4aa3!Pme5Au6#?RHdUtkC{2}#A}V_n+;B9SIf<<%Q(EZ z`sCK^*j~2D=HKg+-oD|n->~5A#?8hrXZGb!yMAr@PJNCL9Ohf?z53*dO68Xo=XBoX zse8`*XZq*o)7Ec==e1_5Ouy$RCVsnk`SO$c_Wfqh_N;sRrMdr~ah}mHnPrBz-;2M< z$yeXK+p_BUS(`uqZcmK+^ycOK%vmXkg_-L%dlpr`eH>HqwD;Pbiyt5V`~LlbLS&p@ zSXkT5$Lg7EzGBnjq%-BFug`yS==JHfI~U*Q|5Wh$n@4h=ar^(%W&c>M)~<^?`|t7Y zoj=b`uPoST`|lPy>H&%WqQebo~*qm+evTl_2){> zJlDni&w28DYSsPw^7USq{=AM`6B%*ag=^B+ulM*o{nNheE#<=!v%mIF+P8f=58Gb( zX~x^OPhYdvw@Pg8>+ep9lkV)i{QBXGi#@R_K5Bsi7VdMJAt{B7v5y{% T>>W|TAQL=Y{an^LB{Ts5{oZ&h diff --git a/third_party/golden/simple/text_3.png b/third_party/golden/simple/text_3.png deleted file mode 100644 index 5f84c89ed03e3a1adebee52851626c435698f7fd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 431 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>pj@PWf^V+V|Jt?>TKQdcSA)y={|@_vM=p-?(djzEbw>ci^etOW(dp)_;2G zLmm5#*W55|P~BLm>1KZ>dP^UBgixHYYHQs$pcA&6hxb##gUUY{Po}8M`2WHA6)31Y MUHx3vIVCg!06b!F=l}o! diff --git a/third_party/golden/simple/text_4.png b/third_party/golden/simple/text_4.png deleted file mode 100644 index 03bf13c643200da41e5c8813f4218db0daa86c31..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1022 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_tI8o-U3d6?5L+-JK;CD8TTb^F~M43jYU7gIRKemUvFoT3ae5fBf9JbK-#> z!W?3c*79WPT#Q#=&<--df_=T~UhkT` zk0ayi%UkMqZmg(1Hs{!#vQ1ZWJhxv7R? znfY(BuD&;McZt~{@bTs4{mJ+D$=2O7eBB~e^!su%yQjHWcG>NA{@C)8E2aMP`SvU4 z=AJb#J2SVkdiVO+mlk$;%lCO#z6yzLj@czr_%`au^Ye%IKR?#{^H|@`$M4^L+o~-a zzHUqK{iS=pZkl|LBY*F$6!pCmBl7o3g;uAX{uZ{Z70AAos=l`|V)whZKqU;X`^#>6 z<||zLwK&oA`PQ7zh1?sj$>*-VrO+?WuRm|G{k!|`v%i0ReKNlLPMv&v``@kMe?uqV z-mcu&rxdrRV@LJ&XEQ%nebst&W@df;-%n5fJ$`-t|MRM>S;cwg`Tu?_c_#d1c{_i5 z`KxEoYLdTydltQU=@YY)ZVwM06iGjuo}CSf8eP@xul_f^y}iAo_<7bm!}W&`cbq-@ zwNNs9+mt)2>>Z8H%?|!)dVJl)jcMK|*H$&#)Z5vVosiYYeseGG$j!}%lYlYlxid6> zLeA%BA=8W&ub*tYeO2~^9tdyx8O80Z{84zklXCBwEbi}*jmiskU!(4?bZ@V;*zb?Y zM~-%X?%7*c`-5LC`s}o6(O+u?W(faxV8@yuai&xzGO`9x%b)c7j9jr?P3Mm5T>+Wk M>FVdQ&MBb@0Pi-<#{d8T diff --git a/third_party/golden/simple/text_5.png b/third_party/golden/simple/text_5.png deleted file mode 100644 index e6142f0a6ff5f25ba9bda42b3077c95887efc15f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 563 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>pxj+g7srr_IdAXo&Xsl)ak#iNWjA~Iq6@k^_^&H)6tEX5uX5gKRhTBcAc*Z# zs8f~Pmggd;IAQJzqRNLG?<-y|3O%4+Kn=HPy7axDT?e4v} ze}(@`=SMm!aIiEvU=oLZtW~>x_wg%Ei6_@TZ@U}wIP>qjx2HeA{(LY~*wR^&G85#D2vr9Ob7)c0gpwb`wag3|3Xb8RSUvLei)6><@ JWt~$(698k5phf@y diff --git a/third_party/golden/simple/text_6.png b/third_party/golden/simple/text_6.png deleted file mode 100644 index a32364feb10b3182a2cdb2e8af6ded3518b4e841..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 692 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_q`$PZ!6KiaBrZ8g?Bq5MXdTzv=(~O?q)3Oq+HeWeY#b=hl|S#5!y1HLHf; z^{d$%tc5vP8XW{^OH{<$GR#kV_Db+lRQBuLyXPlQ=VfwK5MV(k60g0xs$nw$yCgOZ zWQsl9`}^UUn&LkD+qLihzI*;7|KI7IcmF3fV-1HHTdS9H@TXvxq+-C$cx)l})$iB4 z%^!?EKlMCUx$R$EjsOQ!qXGu8Ip*%6^*H3Psi&fteU`0CePG$S)4-I+;OXk;vd$@? F2>@nCq1*rf diff --git a/third_party/golden/simple/use_circles.png b/third_party/golden/simple/use_circles.png deleted file mode 100644 index 46c3aab5eab661e1b19a7054a1d49507b12e3fe6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2496 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 Ni=!uk=5Y1S{{Ru)lpO#7 diff --git a/third_party/golden/simple/use_emc2.png b/third_party/golden/simple/use_emc2.png deleted file mode 100644 index d2e21eca782e6d80c473d3861ce618c3c110ba9e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2494 zcmb_ejX%@dAE%UE$y2VR-P$k0MaZRGX-j#UXCqQbuE!0x>3T>WihIjb2wRuTZp!3w zKW3B7EJ?B{Wo&n58_ilQ{3J&6aKHWjhWmNF&iS0rd7anibI#|y-=A{|{CwQ@su`#$ zDJkuRyE`KQ{pwo-?FRbR3vIQ4Qoe?8JFC?820RNGD%Z}!13`dff}--3l)j6DJ39rY z*USs1Q<{eLZcgK93ps0MHv?|fsM&u1vGGhRgs`JMH*Qy%+6!Rfj2Wm=3DGxsSd?1? zasauOUdNL=IB*RuUCK|SSWRtZAi}>d8-hcX2tEq0aa=oeK zrUiMXy-i>JPU(IpFTtp=j*j2Ed*`fNaZ#}k^3=0v;4GF^Z(9EX4c69%vjc@9k&E*S zN@A6lu?>Et^su{fT8y>6X}|SY1|7P_C@s|-UzB6=O||_?#7~Ui$WoW;{b|uB9>BF! zbX@NJNeH0{;%v)b#~2wqasx{cY@pZ*~8>-&Vgv5{KuJu~A z$tW<|?ys9r<=i*lt1kKa`jU^iH&=bJR>wq#thYSQ|CX3k+Bnp;+z3e%n2jutr8^2w zVe@Sr^#1B!?%CLylPlc162p*)8p?icyF;ayey~zM7p?D_-2)ty(g2!yZXHO7|ImkS z8Fp^ODwi7#^_gU!-}DR^0I5KX#g&p~NZK<+_h0osk8&Xv(2IPf0R-FKwdClq9l zWxZHS7v~ImEoY`kLy(a*RcTr{v$W)2i6HZu99m;WMMB|fFYG*o6Byig8*jcxgVh0G zfH~#P4%91hk!;1Px>pl0=49%a(dexX3wyxTr&QX+Y_4e`vcc+&Mp?4l<1zo>SDCCx zPbHR>`-?r8nbdVE!)hK_WtkPL92tUL{aqN@{&#a;BZ3Rw(Gb;l96#cVt$iGCMkEr+ z@&%r9^1_;7$uF(EHDhJfsE%*3Yw>u=^z`&cE^K?l5Dn%EQL)kO6UDGx$XjOW06Ozc z<7ONh%u*<5e-av3l=ls`XJ%)6=(+&7xqz(~AQ^PJh~THQKr(hzF5{qU4Hk)JB#rGlBp!N*ukR!$5lMAB2as9;j&Gf#Aj7Nz5RD2ZIG zJfZ87oxb{KQGk#*wDJ5ny!?qIxeEWwx}!HcuuXR8(@C&~=7OhyNL9#Nl&VIgH&nT} zw>Pd|k9YLXV|Qq_e9H1JH)5boD&W0gMq)UP!(wDa;>=s#EXxTVCJz zn7zE-GmZ+eynmw}a=womP6S|tv^5}q4Rd&-Rz_F}hL@XiQyPg>Ej~pvY52XJTE8_O z4oz)^LZP3t68J$Lo3JMtbm2R*g2;DsKXXqiPV%QB?Z@v-h;5)Mq7w035{#Lcq_lz3<|vf0x~nPX9RGGIV4^n6iWJ=c?nxj z*Cju_3?9_E{gCtf{LfW}+B}xSN(Q|mKuIFwMx#O-y}JkR%=fZ zjNX&^5bo(WY(J|p#u_?=8$bgr7I896Q(i*oYq`}u>;2Py2X4PxQ}MTAeW=9z>KG<@ zrq=I=V!WRUH?xUwP<+WaJ-<9$t|5B(&MV`*+_|g3ll`Sh(0s$z;I0|1Yd|&@#XEy$ z7+2&-6lY@@$-zxSe+khwznY&zeh=~HlIaYHJB3;<8(igtlGuEdL4C$I&;UqaVy*wPo`0qgEe=3G%Vqo4| zyTgiM&eglzUAz8nuhHq1D7{N^vh3apoe^;iOT?~uWWoa4nBG#fleeonvS@9FbngW!~1Kf|$S~zm_Ie_mesc0qp zHz(Sz?wOqiz_aoKZBZ*tNgXx=>VHxfZQ|lSz{3PC?x!u&)Em@K;jKZ2V+DK0EvWM> zhH+#m!bLmvMvy=fLa$fT_|In)v(qcSOp ztuS*xM^}y@8SK{G)|@E{Zj&|f60lbN^KwP-b!?vyAJLpqGg2@3Y%wP?0_^}Qkd3~& z!BNMK!6bm_ZL$+Sy})JlF0zukSnO`8#jU-$5ybmfstNWb6%8+mWG{u&k12wqssH}x d<^LY{FT+MQeYpJ*Z(n}1;VwSTZD%8L{{efMy|MrR diff --git a/third_party/golden/simple/use_fill.png b/third_party/golden/simple/use_fill.png deleted file mode 100644 index 92e95dc7fcc48709f1f361d17e7c59e11b8f3269..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 873 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_owfPZ!6KiaBrZI2H*xiZER8KXYvANlvFc1MTe(ct5Zl6P|IWVU9vo(*xce zjvrVK_C_BUP7%Agy*u6_!O2Bik?DP?@5RGke7-it-?iO8n*(SAh2Tc%+#s*_`?&A# zJ9_%|?FvKd`oC6r*RSjRurKk_Of9=)A~@g9wdT)^rv1l8v*Y&uDt@{u>-6a+j%_FF zT+XR4yKM8U`9b;T&wcH$4sN?KUv$@98@W$kv+Lw!XD-<+{Vi;*gx9gSf*(`PHvK>B zWqaZf@7zB%8jtyIKU&YcWYw*jj;CrlyQh9uFy74hTgy8*;qqJ86rm3v4BGwozh|Cl zK6l%7_U2L({(0Bqjyz&p`LUw%>E_MbYO1Qf|0?L*<@XP$$jyk#PjD}S84T6p4=`UcD=I4O>n+_^!B6Ae!srHXSD>M z@$0(U-1{7}-+D4V`C*Z+RQmUZf7{onU9-N&&z+l^5EF0zZF1sYIb8?0#ec3(o;`a` zwM5iLULb##+Vq3`Y~Ok|*jgVJUX<4B-HR z8jh3>1_q`IPZ!6KiaBquZ}eqx6mUJrHc>p~SZ+$eL|(RYk}oWEq_(W;df>e_{mbR3 zY~BxxpWkJEU@y$U(&!*SXQE~LU1q;xncd8bg=d#Wzp$Py5 Cx3{SP diff --git a/third_party/golden/simple/use_opacity_grid.png b/third_party/golden/simple/use_opacity_grid.png deleted file mode 100644 index 759ee8ea264591a0e63eb92bdb0d9dea951aa7da..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 957 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 diff --git a/third_party/golden/svg_currentcolor.png b/third_party/golden/svg_currentcolor.png deleted file mode 100644 index 5411bae167ed586b3c9762a7dccef763ffb8b9e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4192 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 AF8}}l diff --git a/third_party/golden/w3samples/aa.png b/third_party/golden/w3samples/aa.png deleted file mode 100644 index b3ba1c78d7fe3082d199c7fea65f25b32acc3d24..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4862 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 diff --git a/third_party/golden/wikimedia/Firefox_Logo_2017.png b/third_party/golden/wikimedia/Firefox_Logo_2017.png deleted file mode 100644 index ec526d7f4b0fdba7560755abc25271a48b224257..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23087 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 diff --git a/third_party/golden/wikimedia/Ghostscript_Tiger.png b/third_party/golden/wikimedia/Ghostscript_Tiger.png deleted file mode 100644 index 030297a761126c3669b1353b34566890a1cff1a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39026 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 avdPictureDecoder( - Uint8List raw, - bool allowDrawingOutsideOfViewBox, - ColorFilter? colorFilter, - String key) async { - final DrawableRoot avdRoot = await fromAvdBytes(raw, key); - final Picture pic = avdRoot.toPicture( - clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, - colorFilter: colorFilter); - return PictureInfo( - picture: pic, - viewport: avdRoot.viewport.viewBoxRect, - compatibilityTester: const CacheCompatibilityTester(), - ); - } - - /// Decodes an Android Vector Drawable from a [String] to a [PictureInfo] - /// object. - Future avdPictureStringDecoder( - String raw, - bool allowDrawingOutsideOfViewBox, - ColorFilter? colorFilter, - String key, - ) async { - final DrawableRoot avdRoot = fromAvdString(raw, key); - final Picture pic = avdRoot.toPicture( - clipToViewBox: allowDrawingOutsideOfViewBox == true ? false : true, - colorFilter: colorFilter, - ); - return PictureInfo( - picture: pic, - viewport: avdRoot.viewport.viewBoxRect, - size: avdRoot.viewport.size, - compatibilityTester: const CacheCompatibilityTester(), - ); - } - - /// Produces a [Drawableroot] from a [Uint8List] of AVD byte data (assumes - /// UTF8 encoding). - /// - /// The `key` parameter is used for debugging purposes. - Future fromAvdBytes(Uint8List raw, String key) async { - // TODO(dnfield): do utf decoding in another thread? - // Might just have to live with potentially slow(ish) decoding, this is causing errors. - // See: https://github.com/dart-lang/sdk/issues/31954 - // See: https://github.com/flutter/flutter/blob/bf3bd7667f07709d0b817ebfcb6972782cfef637/packages/flutter/lib/src/services/asset_bundle.dart#L66 - // if (raw.lengthInBytes < 20 * 1024) { - return fromAvdString(utf8.decode(raw), key); - // } else { - // final String str = - // await compute(_utf8Decode, raw, debugLabel: 'UTF8 decode for SVG'); - // return fromSvgString(str); - // } - } - - // String _utf8Decode(Uint8List data) { - // return utf8.decode(data); - // } - - /// Creates a [DrawableRoot] from a string of Android Vector Drawable data. - DrawableRoot fromAvdString(String rawSvg, String key) { - final XmlElement svg = XmlDocument.parse(rawSvg).rootElement; - final DrawableViewport viewBox = parseViewBox(svg.attributes); - final List children = svg.children - .whereType() - .map((XmlElement child) => parseAvdElement(child, viewBox.viewBoxRect)) - .toList(); - // todo : style on root - return DrawableRoot(getAttribute(svg.attributes, 'id', def: ''), viewBox, - children, DrawableDefinitionServer(), null); - } -} - -/// A widget that draws Android Vector Drawable data into a [Picture] using a -/// [PictureProvider]. -/// -/// Support for AVD is incomplete and experimental at this time. -class AvdPicture extends StatefulWidget { - /// Instantiates a widget that renders an AVD picture using the `pictureProvider`. - /// - /// If `matchTextDirection` is set to true, the picture will be flipped - /// horizontally in [TextDirection.rtl] contexts. - /// - /// The `allowDrawingOutsideOfViewBox` parameter should be used with caution - - /// if set to true, it will not clip the canvas used internally to the view box, - /// meaning the picture may draw beyond the intended area and lead to undefined - /// behavior or additional memory overhead. - /// - /// A custom `placeholderBuilder` can be specified for cases where decoding or - /// acquiring data may take a noticeably long time, e.g. for a network picture. - const AvdPicture( - this.pictureProvider, { - Key? key, - this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false, - this.placeholderBuilder, - this.colorFilter, - }) : super(key: key); - - /// Draws an [AvdPicture] from a raw string of XML. - AvdPicture.string(String bytes, - {bool matchTextDirection = false, - bool allowDrawingOutsideViewBox = false, - WidgetBuilder? placeholderBuilder, - Color? color, - BlendMode colorBlendMode = BlendMode.srcIn, - Key? key}) - : this( - StringPicture( - allowDrawingOutsideViewBox == true - ? (_) => avdStringDecoderOutsideViewBox - : (_) => avdStringDecoder, - bytes, - ), - colorFilter: _getColorFilter(color, colorBlendMode), - matchTextDirection: matchTextDirection, - allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, - placeholderBuilder: placeholderBuilder, - key: key); - - /// Draws an [AvdPicture] from an asset. - AvdPicture.asset(String assetName, - {Key? key, - bool matchTextDirection = false, - AssetBundle? bundle, - String? package, - bool allowDrawingOutsideViewBox = false, - WidgetBuilder? placeholderBuilder, - Color? color, - BlendMode colorBlendMode = BlendMode.srcIn}) - : this( - ExactAssetPicture( - allowDrawingOutsideViewBox == true - ? (_) => avdStringDecoderOutsideViewBox - : (_) => avdStringDecoder, - assetName, - bundle: bundle, - package: package, - ), - colorFilter: _getColorFilter(color, colorBlendMode), - matchTextDirection: matchTextDirection, - allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, - placeholderBuilder: placeholderBuilder, - key: key); - - /// The default placeholder for an AVD that may take time to parse or - /// retrieve, e.g. from a network location. - static WidgetBuilder defaultPlaceholderBuilder = - (BuildContext ctx) => const LimitedBox(); - - static ColorFilter? _getColorFilter(Color? color, BlendMode colorBlendMode) => - color == null ? null : ColorFilter.mode(color, colorBlendMode); - - /// A [PictureInfoDecoder] for [Uint8List]s that will clip to the viewBox. - static final PictureInfoDecoder avdByteDecoder = - (Uint8List bytes, ColorFilter? colorFilter, String key) => - avd.avdPictureDecoder(bytes, false, colorFilter, key); - - /// A [PictureInfoDecoder] for strings that will clip to the viewBox. - static final PictureInfoDecoder avdStringDecoder = - (String data, ColorFilter? colorFilter, String key) => - avd.avdPictureStringDecoder(data, false, colorFilter, key); - - /// A [PictureInfoDecoder] for [Uint8List]s that will not clip to the viewBox. - static final PictureInfoDecoder avdByteDecoderOutsideViewBox = - (Uint8List bytes, ColorFilter? colorFilter, String key) => - avd.avdPictureDecoder(bytes, true, colorFilter, key); - - /// A [PictureInfoDecoder] for [String]s that will not clip to the viewBox. - static final PictureInfoDecoder avdStringDecoderOutsideViewBox = - (String data, ColorFilter? colorFilter, String key) => - avd.avdPictureStringDecoder(data, true, colorFilter, key); - - /// The [PictureProvider] used to resolve the AVD. - final PictureProvider pictureProvider; - - /// The placeholder to use while fetching, decoding, and parsing the AVD data. - final WidgetBuilder? placeholderBuilder; - - /// If true, will horizontally flip the picture in [TextDirection.rtl] contexts. - final bool matchTextDirection; - - /// If true, will allow the AVD to be drawn outside of the clip boundary of its - /// viewBox. - final bool allowDrawingOutsideViewBox; - - /// The color filter, if any, to apply to this widget. - final ColorFilter? colorFilter; - - @override - State createState() => _AvdPictureState(); -} - -class _AvdPictureState extends State { - PictureInfo? _picture; - PictureStream? _pictureStream; - bool _isListeningToStream = false; - - @override - void didChangeDependencies() { - _resolveImage(); - - if (TickerMode.of(context)) { - _listenToStream(); - } else { - _stopListeningToStream(); - } - super.didChangeDependencies(); - } - - @override - void didUpdateWidget(AvdPicture oldWidget) { - super.didUpdateWidget(oldWidget); - if (widget.pictureProvider != oldWidget.pictureProvider) { - _resolveImage(); - } - } - - @override - void reassemble() { - _resolveImage(); // in case the image cache was flushed - super.reassemble(); - } - - void _resolveImage() { - final PictureStream newStream = widget.pictureProvider - .resolve(createLocalPictureConfiguration(context)); - assert(newStream != null); // ignore: unnecessary_null_comparison - _updateSourceStream(newStream); - } - - void _handleImageChanged(PictureInfo? imageInfo, bool synchronousCall) { - setState(() { - _picture = imageInfo; - }); - } - - // Update _pictureStream to newStream, and moves the stream listener - // registration from the old stream to the new stream (if a listener was - // registered). - void _updateSourceStream(PictureStream newStream) { - if (_pictureStream?.key == newStream.key) { - return; - } - - if (_isListeningToStream) - _pictureStream!.removeListener(_handleImageChanged); - - _pictureStream = newStream; - if (_isListeningToStream) { - _pictureStream!.addListener(_handleImageChanged); - } - } - - void _listenToStream() { - if (_isListeningToStream) { - return; - } - _pictureStream!.addListener(_handleImageChanged); - _isListeningToStream = true; - } - - void _stopListeningToStream() { - if (!_isListeningToStream) { - return; - } - _pictureStream!.removeListener(_handleImageChanged); - _isListeningToStream = false; - } - - @override - void dispose() { - assert(_pictureStream != null); - _stopListeningToStream(); - super.dispose(); - } - - @override - Widget build(BuildContext context) { - late Widget child; - if (_picture != null) { - final Rect viewport = Offset.zero & _picture!.viewport.size; - - child = SizedBox( - width: viewport.width, - height: viewport.height, - child: FittedBox( - clipBehavior: Clip.hardEdge, - child: SizedBox.fromSize( - size: viewport.size, - child: RawPicture( - _picture, - matchTextDirection: widget.matchTextDirection, - allowDrawingOutsideViewBox: widget.allowDrawingOutsideViewBox, - ), - ), - ), - ); - - if (widget.pictureProvider.colorFilter == null && - widget.colorFilter != null) { - child = ColorFiltered( - colorFilter: widget.colorFilter!, - child: child, - ); - } - } else { - child = AvdPicture.defaultPlaceholderBuilder(context); - } - return child; - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder description) { - super.debugFillProperties(description); - description.add( - DiagnosticsProperty('stream', _pictureStream), - ); - } -} diff --git a/third_party/lib/flutter_svg.dart b/third_party/lib/flutter_svg.dart index 338ad186b778..eb6d4b5ab9e8 100644 --- a/third_party/lib/flutter_svg.dart +++ b/third_party/lib/flutter_svg.dart @@ -1,6 +1 @@ -export 'src/picture_provider.dart'; -export 'src/picture_stream.dart'; -export 'src/svg/default_theme.dart'; -export 'src/svg/theme.dart'; -export 'src/vector_drawable.dart'; export 'svg.dart'; diff --git a/third_party/lib/parser.dart b/third_party/lib/parser.dart deleted file mode 100644 index ee2e4eb262c9..000000000000 --- a/third_party/lib/parser.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:xml/xml_events.dart' as xml show parseEvents; - -import 'src/svg/parser_state.dart'; -import 'src/svg/theme.dart'; -import 'src/vector_drawable.dart'; - -/// Parses SVG data into a [DrawableRoot]. -class SvgParser { - /// Parses SVG from a string to a [DrawableRoot] with the provided [theme]. - /// - /// The [key] parameter is used for debugging purposes. - /// - /// By default SVG parsing will only log warnings when detecting unsupported - /// elements in an SVG. - /// If [warningsAsErrors] is true the function will throw with an error - /// instead. - /// You might want to set this to true for test and to false at runtime. - /// Defaults to false. - Future parse( - String str, { - SvgTheme theme = const SvgTheme(), - String? key, - bool warningsAsErrors = false, - }) async { - final SvgParserState state = - SvgParserState(xml.parseEvents(str), theme, key, warningsAsErrors); - return await state.parse(); - } -} diff --git a/third_party/lib/src/avd/xml_parsers.dart b/third_party/lib/src/avd/xml_parsers.dart deleted file mode 100644 index 6576bbd0e19f..000000000000 --- a/third_party/lib/src/avd/xml_parsers.dart +++ /dev/null @@ -1,273 +0,0 @@ -import 'dart:math'; -import 'dart:ui'; - -import 'package:vector_math/vector_math_64.dart'; -import 'package:xml/xml.dart'; - -import '../utilities/numbers.dart'; -import '../vector_drawable.dart'; - -/// The AVD namespace. -const String androidNS = 'http://schemas.android.com/apk/res/android'; - -/// A utility method for getting an XML attribute with a default value. -String? getAttribute( - List attributes, - String name, { - String? def = '', - String? namespace, -}) { - for (XmlAttribute attribute in attributes) { - if (attribute.name.local == name) { - return attribute.value; - } - } - return def; -} - -/// Parses an AVD @android:viewportWidth and @android:viewportHeight attributes to a [Rect]. -DrawableViewport parseViewBox(List el) { - final String? rawWidth = - getAttribute(el, 'viewportWidth', def: '', namespace: androidNS); - final String? rawHeight = - getAttribute(el, 'viewportHeight', def: '', namespace: androidNS); - if (rawWidth == '' || rawHeight == '') { - return const DrawableViewport(Size.zero, Size.zero); - } - final double width = parseDouble(rawWidth)!; - final double height = parseDouble(rawHeight)!; - return DrawableViewport( - Size(width, height), - Size(width, height), - ); -} - -/// Parses AVD transform related attributes to a [Matrix4]. -Matrix4 parseTransform(List el) { - final double rotation = parseDouble( - getAttribute(el, 'rotation', def: '0', namespace: androidNS))!; - final double pivotX = - parseDouble(getAttribute(el, 'pivotX', def: '0', namespace: androidNS))!; - final double pivotY = - parseDouble(getAttribute(el, 'pivotY', def: '0', namespace: androidNS))!; - final double? scaleX = - parseDouble(getAttribute(el, 'scaleX', def: '1', namespace: androidNS)); - final double? scaleY = - parseDouble(getAttribute(el, 'scaleY', def: '1', namespace: androidNS)); - final double translateX = parseDouble( - getAttribute(el, 'translateX', def: '0', namespace: androidNS))!; - final double translateY = parseDouble( - getAttribute(el, 'translateY', def: '0', namespace: androidNS))!; - - return Matrix4.identity() - ..translate(pivotX, pivotY) - ..rotateZ(rotation * pi / 180) - ..scale(scaleX, scaleY) - ..translate(-pivotX + translateX, -pivotY + translateY); -} - -/// Parses an AVD stroke related attributes to a [DrawablePaint]. -DrawablePaint? parseStroke(List el, Rect bounds) { - final String? rawStroke = - getAttribute(el, 'strokeColor', def: null, namespace: androidNS); - if (rawStroke == null) { - return null; - } - return DrawablePaint( - PaintingStyle.stroke, - color: parseColor(rawStroke)!.withOpacity(parseDouble( - getAttribute(el, 'strokeAlpha', def: '1', namespace: androidNS))!), - strokeWidth: parseDouble( - getAttribute(el, 'strokeWidth', def: '0', namespace: androidNS)), - strokeCap: parseStrokeCap(el), - strokeJoin: parseStrokeJoin(el), - strokeMiterLimit: parseMiterLimit(el), - ); -} - -/// Parses AVD `strokeMiterLimit` to a double. -double? parseMiterLimit(List el) { - return parseDouble( - getAttribute(el, 'strokeMiterLimit', def: '4', namespace: androidNS)); -} - -/// Parses AVD `strokeLineJoin` to a [StrokeJoin]. -StrokeJoin parseStrokeJoin(List el) { - final String? rawStrokeJoin = - getAttribute(el, 'strokeLineJoin', def: 'miter', namespace: androidNS); - switch (rawStrokeJoin) { - case 'miter': - return StrokeJoin.miter; - case 'bevel': - return StrokeJoin.bevel; - case 'round': - return StrokeJoin.round; - default: - return StrokeJoin.miter; - } -} - -/// Parses the `strokeLineCap` to a [StrokeCap]. -StrokeCap parseStrokeCap(List el) { - final String? rawStrokeCap = - getAttribute(el, 'strokeLineCap', def: 'butt', namespace: androidNS); - switch (rawStrokeCap) { - case 'butt': - return StrokeCap.butt; - case 'round': - return StrokeCap.round; - case 'square': - return StrokeCap.square; - default: - return StrokeCap.butt; - } -} - -/// Parses fill information to a [DrawablePaint]. -DrawablePaint? parseFill(List el, Rect bounds) { - final String? rawFill = - getAttribute(el, 'fillColor', def: null, namespace: androidNS); - if (rawFill == null) { - return null; - } - return DrawablePaint( - PaintingStyle.fill, - color: parseColor(rawFill)! - .withOpacity(parseDouble(getAttribute(el, 'fillAlpha', def: '1'))!), - ); -} - -/// Turns a `fillType` into a [PathFillType]. -PathFillType parsePathFillType(List el) { - final String? rawFillType = - getAttribute(el, 'fillType', def: 'nonZero', namespace: androidNS); - return rawFillType == 'nonZero' ? PathFillType.nonZero : PathFillType.evenOdd; -} - -/// Converts a SVG Color String (either a # prefixed color string or a named color) to a [Color]. -Color? parseColor(String? colorString) { - if (colorString == null || colorString.isEmpty) { - return null; - } - - if (colorString == 'none') { - return null; - } - - // handle hex colors e.g. #fff or #ffffff. This supports #RRGGBBAA - if (colorString[0] == '#') { - if (colorString.length == 4) { - final String r = colorString[1]; - final String g = colorString[2]; - final String b = colorString[3]; - colorString = '#$r$r$g$g$b$b'; - } - int color = int.parse(colorString.substring(1), radix: 16); - - if (colorString.length == 7) { - return Color(color |= 0xFF000000); - } - - if (colorString.length == 9) { - return Color(color); - } - } - - // handle rgba() colors e.g. rgba(255, 255, 255, 1.0) - if (colorString.toLowerCase().startsWith('rgba')) { - final List rawColorElements = colorString - .substring(colorString.indexOf('(') + 1, colorString.indexOf(')')) - .split(',') - .map((String rawColor) => rawColor.trim()) - .toList(); - - final double opacity = parseDouble(rawColorElements.removeLast())!; - - final List rgb = - rawColorElements.map((String rawColor) => int.parse(rawColor)).toList(); - - return Color.fromRGBO(rgb[0], rgb[1], rgb[2], opacity); - } - - // Conversion code from: https://github.com/MichaelFenwick/Color, thanks :) - if (colorString.toLowerCase().startsWith('hsl')) { - final List values = colorString - .substring(colorString.indexOf('(') + 1, colorString.indexOf(')')) - .split(',') - .map((String rawColor) { - rawColor = rawColor.trim(); - - if (rawColor.endsWith('%')) { - rawColor = rawColor.substring(0, rawColor.length - 1); - } - - if (rawColor.contains('.')) { - return (parseDouble(rawColor)! * 2.55).round(); - } - - return int.parse(rawColor); - }).toList(); - final double hue = values[0] / 360 % 1; - final double saturation = values[1] / 100; - final double luminance = values[2] / 100; - final int alpha = values.length > 3 ? values[3] : 255; - List rgb = [0, 0, 0]; - - if (hue < 1 / 6) { - rgb[0] = 1; - rgb[1] = hue * 6; - } else if (hue < 2 / 6) { - rgb[0] = 2 - hue * 6; - rgb[1] = 1; - } else if (hue < 3 / 6) { - rgb[1] = 1; - rgb[2] = hue * 6 - 2; - } else if (hue < 4 / 6) { - rgb[1] = 4 - hue * 6; - rgb[2] = 1; - } else if (hue < 5 / 6) { - rgb[0] = hue * 6 - 4; - rgb[2] = 1; - } else { - rgb[0] = 1; - rgb[2] = 6 - hue * 6; - } - - rgb = - rgb.map((double val) => val + (1 - saturation) * (0.5 - val)).toList(); - - if (luminance < 0.5) { - rgb = rgb.map((double val) => luminance * 2 * val).toList(); - } else { - rgb = rgb - .map((double val) => luminance * 2 * (1 - val) + 2 * val - 1) - .toList(); - } - - rgb = rgb.map((double val) => val * 255).toList(); - - return Color.fromARGB( - alpha, rgb[0].round(), rgb[1].round(), rgb[2].round()); - } - - // handle rgb() colors e.g. rgb(255, 255, 255) - if (colorString.toLowerCase().startsWith('rgb')) { - final List rgb = colorString - .substring(colorString.indexOf('(') + 1, colorString.indexOf(')')) - .split(',') - .map((String rawColor) { - rawColor = rawColor.trim(); - if (rawColor.endsWith('%')) { - rawColor = rawColor.substring(0, rawColor.length - 1); - return (parseDouble(rawColor)! * 2.55).round(); - } - return int.parse(rawColor); - }).toList(); - - // rgba() isn't really in the spec, but Firefox supported it at one point so why not. - final int a = rgb.length > 3 ? rgb[3] : 255; - return Color.fromARGB(a, rgb[0], rgb[1], rgb[2]); - } - - throw StateError('Could not parse "$colorString" as a color.'); -} diff --git a/third_party/lib/src/avd_parser.dart b/third_party/lib/src/avd_parser.dart deleted file mode 100644 index 37209a3fd674..000000000000 --- a/third_party/lib/src/avd_parser.dart +++ /dev/null @@ -1,74 +0,0 @@ -import 'dart:ui'; - -import 'package:path_drawing/path_drawing.dart'; -import 'package:vector_math/vector_math_64.dart'; -import 'package:xml/xml.dart'; - -import 'avd/xml_parsers.dart'; -import 'vector_drawable.dart'; - -/// An AVD path element that will be drawn to the canvas. -class DrawableAvdPath extends DrawableShape { - /// An AVD path element that will be drawn to the canvas. - const DrawableAvdPath(String? id, Path path, DrawableStyle style) - : super(id, path, style); - - /// Creates a [DrawableAvdPath] from an XML element - factory DrawableAvdPath.fromXml(XmlElement el) { - final String d = - getAttribute(el.attributes, 'pathData', def: '', namespace: androidNS)!; - final Path path = parseSvgPathData(d); - assert(path != null); // ignore: unnecessary_null_comparison - - path.fillType = parsePathFillType(el.attributes); - final DrawablePaint? stroke = parseStroke(el.attributes, path.getBounds()); - final DrawablePaint? fill = parseFill(el.attributes, path.getBounds()); - - return DrawableAvdPath( - getAttribute(el.attributes, 'id', def: ''), - path, - DrawableStyle(stroke: stroke, fill: fill), - ); - } -} - -/// Creates a [Drawable] from an SVG or shape element. Also handles parsing and gradients. -/// -/// If an unsupported element is encountered, it will be created as a [DrawableNoop]. -Drawable parseAvdElement(XmlElement el, Rect bounds) { - if (el.name.local == 'path') { - return DrawableAvdPath.fromXml(el); - } else if (el.name.local == 'group') { - return parseAvdGroup(el, bounds); - } - // TODO(dnfield): clipPath - print('Unhandled element ${el.name.local}'); - return const DrawableGroup('', null, null); -} - -/// Parses an AVD element. -Drawable parseAvdGroup(XmlElement el, Rect bounds) { - final List children = []; - for (XmlNode child in el.children) { - if (child is XmlElement) { - final Drawable el = parseAvdElement(child, bounds); - children.add(el); - } - } - - final Matrix4 transform = parseTransform(el.attributes); - - final DrawablePaint? fill = parseFill(el.attributes, bounds); - final DrawablePaint? stroke = parseStroke(el.attributes, bounds); - - return DrawableGroup( - getAttribute(el.attributes, 'id', def: ''), - children, - DrawableStyle( - stroke: stroke, - fill: fill, - groupOpacity: 1.0, - ), - transform: transform.storage, - ); -} diff --git a/third_party/lib/src/picture_cache.dart b/third_party/lib/src/cache.dart similarity index 69% rename from third_party/lib/src/picture_cache.dart rename to third_party/lib/src/cache.dart index ddf133124fe4..3eb9fba25359 100644 --- a/third_party/lib/src/picture_cache.dart +++ b/third_party/lib/src/cache.dart @@ -1,21 +1,17 @@ -import 'picture_stream.dart'; -import 'svg/theme.dart'; +import 'package:flutter/foundation.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; -const int _kDefaultSize = 1000; - -/// A cache for [PictureLayer] objects. -/// -/// By default, this caches up to 1000 objects. -class PictureCache { - final Map _cache = - {}; +/// The cache for decoded SVGs. +class Cache { + final Map> _pending = >{}; + final Map _cache = {}; /// Maximum number of entries to store in the cache. /// /// Once this many entries have been cached, the least-recently-used entry is /// evicted when adding a new entry. int get maximumSize => _maximumSize; - int _maximumSize = _kDefaultSize; + int _maximumSize = 100; /// Changes the maximum cache size. /// @@ -34,7 +30,7 @@ class PictureCache { clear(); } else { while (_cache.length > maximumSize) { - _cache.remove(_cache.keys.first)!.cached = false; + _cache.remove(_cache.keys.first); } } } @@ -44,10 +40,6 @@ class PictureCache { /// This is useful if, for instance, the root asset bundle has been updated /// and therefore new images must be obtained. void clear() { - for (final PictureStreamCompleter completer in _cache.values) { - assert(completer.cached); - completer.cached = false; - } _cache.clear(); } @@ -62,9 +54,6 @@ class PictureCache { /// For example, if the theme has changed the current color and the picture /// uses current color, [evict] will be called. bool maybeEvict(Object key, SvgTheme oldData, SvgTheme newData) { - if (_cache[key]?.isCompatible(oldData, newData) ?? true) { - return false; - } return evict(key); } @@ -73,30 +62,49 @@ class PictureCache { /// key is moved to the "most recently used" position. /// /// The arguments must not be null. The `loader` cannot return null. - PictureStreamCompleter putIfAbsent( + Future putIfAbsent( Object key, - PictureStreamCompleter loader(), + Future loader(), ) { assert(key != null); // ignore: unnecessary_null_comparison assert(loader != null); // ignore: unnecessary_null_comparison - PictureStreamCompleter? result = _cache[key]; + Future? pendingResult = _pending[key]; + if (pendingResult != null) { + return pendingResult; + } + + ByteData? result = _cache[key]; if (result != null) { // Remove the provider from the list so that we can put it back in below // and thus move it to the end of the list. _cache.remove(key); } else { if (_cache.length == maximumSize && maximumSize > 0) { - _cache.remove(_cache.keys.first)!.cached = false; + _cache.remove(_cache.keys.first); } - result = loader(); + pendingResult = loader(); + _pending[key] = pendingResult; + pendingResult.then((ByteData data) { + _pending.remove(key); + _add(key, data); + + result = data; // in case it was a synchronous future. + }); } + if (result != null) { + _add(key, result!); + return SynchronousFuture(result!); + } + assert(_cache.length <= maximumSize); + return pendingResult!; + } + + void _add(Object key, ByteData result) { if (maximumSize > 0) { assert(_cache.length < maximumSize); _cache[key] = result; - result.cached = true; } assert(_cache.length <= maximumSize); - return result; } /// The number of entries in the cache. diff --git a/third_party/lib/src/loaders.dart b/third_party/lib/src/loaders.dart new file mode 100644 index 000000000000..81750c3ef705 --- /dev/null +++ b/third_party/lib/src/loaders.dart @@ -0,0 +1,287 @@ +import 'dart:convert' show utf8; + +import 'package:flutter/foundation.dart' hide compute; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/src/utilities/http.dart'; +import 'package:vector_graphics/vector_graphics.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; + +import '../svg.dart' show svg; +import 'utilities/compute.dart'; +import 'utilities/file.dart'; + +/// A [BytesLoader] that parses a SVG data in an isolate and creates a +/// vector_graphics binary representation. +abstract class SvgLoader extends BytesLoader { + /// See class doc. + const SvgLoader({ + this.theme = const SvgTheme(), + this.colorMapper, + }); + + /// The theme to determine currentColor and font sizing attributes. + final SvgTheme theme; + + /// The [ColorMapper] used to transform colors from the SVG, if any. + final ColorMapper? colorMapper; + + /// Will be called in [compute] with the result of [prepareMessage]. + @protected + String provideSvg(T? message); + + /// Will be called + @protected + Future prepareMessage(BuildContext? context) => + SynchronousFuture(null); + + /// This method intentionally avoids using `await` to avoid unnecessary event + /// loop turns. This is meant to to help tests in particular. + @override + Future loadBytes(BuildContext? context) { + return svg.cache.putIfAbsent(cacheKey(context), () { + return prepareMessage(context).then((T? message) { + return compute((T? message) { + return encodeSvg( + xml: provideSvg(message), + theme: theme, + colorMapper: colorMapper, + debugName: 'Svg loader', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ).buffer.asByteData(); + }, message, debugLabel: 'Load Bytes'); + }); + }); + } +} + +/// A [BytesLoader] that parses an SVG string in an isolate and creates a +/// vector_graphics binary representation. +class SvgStringLoader extends SvgLoader { + /// See class doc. + const SvgStringLoader( + this._svg, { + super.theme, + super.colorMapper, + }); + + final String _svg; + + @override + String provideSvg(void message) { + return _svg; + } + + @override + int get hashCode => Object.hash(svg, theme, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgStringLoader && + other._svg == _svg && + other.theme == theme && + other.colorMapper == colorMapper; + } +} + +/// A [BytesLoader] that decodes and parses a UTF-8 encoded SVG string from a +/// [Uint8List] in an isolate and creates a vector_graphics binary +/// representation. +class SvgBytesLoader extends SvgLoader { + /// See class doc. + const SvgBytesLoader( + this.bytes, { + super.theme, + super.colorMapper, + }); + + /// The UTF-8 encoded XML bytes. + final Uint8List bytes; + + @override + String provideSvg(void message) => utf8.decode(bytes); + + @override + int get hashCode => Object.hash(svg, theme, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgBytesLoader && + other.bytes == bytes && + other.theme == theme && + other.colorMapper == colorMapper; + } +} + +/// A [BytesLoader] that decodes SVG data from a file in an isolate and creates +/// a vector_graphics binary representation. +class SvgFileLoader extends SvgLoader { + /// See class doc. + const SvgFileLoader( + this.file, { + super.theme, + super.colorMapper, + }); + + /// The file containing the SVG data to decode and render. + final File file; + + @override + String provideSvg(void message) { + final Uint8List bytes = file.readAsBytesSync(); + return utf8.decode(bytes); + } + + @override + int get hashCode => Object.hash(file, theme, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgFileLoader && + other.file == file && + other.theme == theme && + other.colorMapper == colorMapper; + } +} + +// Replaces the cache key for [AssetBytesLoader] to account for the fact that +// different widgets may select a different asset bundle based on the return +// value of `DefaultAssetBundle.of(context)`. +@immutable +class _AssetByteLoaderCacheKey { + const _AssetByteLoaderCacheKey( + this.assetName, + this.packageName, + this.assetBundle, + ); + + final String assetName; + final String? packageName; + + final AssetBundle assetBundle; + + @override + int get hashCode => Object.hash(assetName, packageName, assetBundle); + + @override + bool operator ==(Object other) { + return other is _AssetByteLoaderCacheKey && + other.assetName == assetName && + other.assetBundle == assetBundle && + other.packageName == packageName; + } + + @override + String toString() => + 'VectorGraphicAsset(${packageName != null ? '$packageName/' : ''}$assetName)'; +} + +/// A [BytesLoader] that decodes and parses an SVG asset in an isolate and +/// creates a vector_graphics binary representation. +class SvgAssetLoader extends SvgLoader { + /// See class doc. + const SvgAssetLoader( + this.assetName, { + this.packageName, + this.assetBundle, + super.theme, + super.colorMapper, + }); + + /// The name of the asset, e.g. foo.svg. + final String assetName; + + /// The package containing the asset. + final String? packageName; + + /// The asset bundle to use, or [DefaultAssetBundle] if null. + final AssetBundle? assetBundle; + + AssetBundle _resolveBundle(BuildContext? context) { + if (assetBundle != null) { + return assetBundle!; + } + if (context != null) { + return DefaultAssetBundle.of(context); + } + return rootBundle; + } + + @override + Future prepareMessage(BuildContext? context) { + return _resolveBundle(context).load(assetName); + } + + @override + String provideSvg(ByteData? message) => + utf8.decode(message!.buffer.asUint8List()); + + @override + Object cacheKey(BuildContext? context) { + return _AssetByteLoaderCacheKey( + assetName, + packageName, + _resolveBundle(context), + ); + } + + @override + int get hashCode => + Object.hash(assetName, packageName, assetBundle, theme, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgAssetLoader && + other.assetName == assetName && + other.packageName == packageName && + other.assetBundle == assetBundle && + other.theme == theme && + other.colorMapper == colorMapper; + } + + @override + String toString() => 'SvgAssetLoader($assetName)'; +} + +/// A [BytesLoader] that decodes and parses a UTF-8 encoded SVG string the +/// network in an isolate and creates a vector_graphics binary representation. +class SvgNetworkLoader extends SvgLoader { + /// See class doc. + const SvgNetworkLoader( + this.url, { + this.headers, + super.theme, + super.colorMapper, + }); + + /// The [Uri] encoded resource address. + final String url; + + /// Optional HTTP headers to send as part of the request. + final Map? headers; + + @override + Future prepareMessage(BuildContext? context) { + return httpGet(url, headers: headers); + } + + @override + String provideSvg(Uint8List? message) => utf8.decode(message!); + + @override + int get hashCode => Object.hash(url, headers, theme, colorMapper); + + @override + bool operator ==(Object other) { + return other is SvgNetworkLoader && + other.url == url && + other.headers == headers && + other.theme == theme && + other.colorMapper == colorMapper; + } + + @override + String toString() => 'SvgNetworkLoader($url)'; +} diff --git a/third_party/lib/src/picture_provider.dart b/third_party/lib/src/picture_provider.dart deleted file mode 100644 index bb6cb12d4700..000000000000 --- a/third_party/lib/src/picture_provider.dart +++ /dev/null @@ -1,982 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; -import 'dart:typed_data'; // ignore: unnecessary_import -import 'dart:ui' - show BlendMode, Color, ColorFilter, Locale, Rect, TextDirection; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart' - show BuildContext, DefaultAssetBundle, Directionality, Localizations; - -import 'picture_cache.dart'; -import 'picture_stream.dart'; -import 'svg/theme.dart'; -import 'utilities/file.dart'; -import 'utilities/http.dart'; - -/// The signature of a function that can decode raw SVG data into a [Picture]. -/// -/// Used by [PictureProvider]. Several useful methods are provided in the [Svg] -/// class. -typedef PictureInfoDecoder = Future Function( - T data, - ColorFilter? colorFilter, - String key, -); - -/// The signature of a builder that returns a [PictureInfoDecoder] -/// based on the provided [theme]. -typedef PictureInfoDecoderBuilder = PictureInfoDecoder Function( - SvgTheme theme, -); - -/// Creates an [PictureConfiguration] based on the given [BuildContext] (and -/// optionally size). -/// -/// This is the object that must be passed to [PictureProvider.resolve]. -/// -/// If this is not called from a build method, then it should be reinvoked -/// whenever the dependencies change, e.g. by calling it from -/// [State.didChangeDependencies], so that any changes in the environment are -/// picked up (e.g. if the device pixel ratio changes). -/// -/// See also: -/// -/// * [PictureProvider], which has an example showing how this might be used. -PictureConfiguration createLocalPictureConfiguration( - BuildContext? context, { - Rect? viewBox, - ColorFilter? colorFilterOverride, - Color? color, - BlendMode? colorBlendMode, -}) { - ColorFilter? filter = colorFilterOverride; - if (filter == null && color != null) { - filter = ColorFilter.mode(color, colorBlendMode ?? BlendMode.srcIn); - } - return PictureConfiguration( - bundle: context != null ? DefaultAssetBundle.of(context) : rootBundle, - locale: context != null ? Localizations.maybeLocaleOf(context) : null, - textDirection: context != null ? Directionality.maybeOf(context) : null, - viewBox: viewBox, - platform: defaultTargetPlatform, - colorFilter: filter, - ); -} - -/// Configuration information passed to the [PictureProvider.resolve] method to -/// select a specific picture. -/// -/// See also: -/// -/// * [createLocalPictureConfiguration], which creates an [PictureConfiguration] -/// based on ambient configuration in a [Widget] environment. -/// * [PictureProvider], which uses [PictureConfiguration] objects to determine -/// which picture to obtain. -@immutable -class PictureConfiguration { - /// Creates an object holding the configuration information for an [PictureProvider]. - /// - /// All the arguments are optional. Configuration information is merely - /// advisory and best-effort. - const PictureConfiguration({ - this.bundle, - this.locale, - this.textDirection, - this.viewBox, - this.platform, - this.colorFilter, - }); - - /// Creates an object holding the configuration information for an [PictureProvider]. - /// - /// All the arguments are optional. Configuration information is merely - /// advisory and best-effort. - PictureConfiguration copyWith({ - AssetBundle? bundle, - Locale? locale, - TextDirection? textDirection, - Rect? viewBox, - TargetPlatform? platform, - ColorFilter? colorFilter, - }) { - return PictureConfiguration( - bundle: bundle ?? this.bundle, - locale: locale ?? this.locale, - textDirection: textDirection ?? this.textDirection, - viewBox: viewBox ?? this.viewBox, - platform: platform ?? this.platform, - colorFilter: colorFilter ?? this.colorFilter, - ); - } - - /// The preferred [AssetBundle] to use if the [PictureProvider] needs one and - /// does not have one already selected. - final AssetBundle? bundle; - - /// The language and region for which to select the picture. - final Locale? locale; - - /// The reading direction of the language for which to select the picture. - final TextDirection? textDirection; - - /// The size at which the picture will be rendered. - final Rect? viewBox; - - /// The [TargetPlatform] for which assets should be used. This allows pictures - /// to be specified in a platform-neutral fashion yet use different assets on - /// different platforms, to match local conventions e.g. for color matching or - /// shadows. - final TargetPlatform? platform; - - /// The [ColorFilter], if any, that was applied to the drawing. - final ColorFilter? colorFilter; - - /// a picture configuration that provides no additional information. - /// - /// Useful when resolving an [PictureProvider] without any context. - static const PictureConfiguration empty = PictureConfiguration(); - - @override - bool operator ==(dynamic other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is PictureConfiguration && - other.bundle == bundle && - other.locale == locale && - other.textDirection == textDirection && - other.viewBox == viewBox && - other.platform == platform && - other.colorFilter == colorFilter; - } - - @override - int get hashCode => - Object.hash(bundle, locale, viewBox, platform, colorFilter); - - @override - String toString() { - final StringBuffer result = StringBuffer(); - result.write('PictureConfiguration('); - bool hasArguments = false; - if (bundle != null) { - result.write('bundle: $bundle'); - hasArguments = true; - } - if (locale != null) { - if (hasArguments) { - result.write(', '); - } - result.write('locale: $locale'); - hasArguments = true; - } - if (textDirection != null) { - if (hasArguments) { - result.write(', '); - } - result.write('textDirection: $textDirection'); - hasArguments = true; - } - if (viewBox != null) { - if (hasArguments) { - result.write(', '); - } - result.write('viewBox: $viewBox'); - hasArguments = true; - } - if (platform != null) { - if (hasArguments) { - result.write(', '); - } - result.write('platform: ${describeEnum(platform!)}'); - hasArguments = true; - } - if (colorFilter != null) { - if (hasArguments) { - result.write(', '); - } - result.write('colorFilter: $colorFilter'); - hasArguments = true; - } - result.write(')'); - return result.toString(); - } -} - -/// Identifies a picture without committing to the precise final asset. This -/// allows a set of pictures to be identified and for the precise picture to later -/// be resolved based on the environment, e.g. the device pixel ratio. -/// -/// To obtain an [PictureStream] from an [PictureProvider], call [resolve], -/// passing it an [PictureConfiguration] object. -/// -/// [PictureProvider] uses the global [pictureCache] to cache pictures. -/// -/// The type argument `T` is the type of the object used to represent a resolved -/// configuration. This is also the type used for the key in the picture cache. It -/// should be immutable and implement the [==] operator and the [hashCode] -/// getter. Subclasses should subclass a variant of [PictureProvider] with an -/// explicit `T` type argument. -/// -/// The type argument does not have to be specified when using the type as an -/// argument (where any Picture provider is acceptable). -/// -/// The following picture formats are supported: {@macro flutter.dart:ui.pictureFormats} -/// -/// ## Sample code -/// -/// The following shows the code required to write a widget that fully conforms -/// to the [PictureProvider] and [Widget] protocols. (It is essentially a -/// bare-bones version of the [widgets.Picture] widget.) -/// -/// ```dart -/// class MyPicture extends StatefulWidget { -/// const MyPicture({ -/// Key key, -/// @required this.PictureProvider, -/// }) : assert(PictureProvider != null), -/// super(key: key); -/// -/// final PictureProvider PictureProvider; -/// -/// @override -/// _MyPictureState createState() => _MyPictureState(); -/// } -/// -/// class _MyPictureState extends State { -/// PictureStream _PictureStream; -/// PictureInfo _pictureInfo; -/// -/// @override -/// void didChangeDependencies() { -/// super.didChangeDependencies(); -/// // We call _getPicture here because createLocalPictureConfiguration() needs to -/// // be called again if the dependencies changed, in case the changes relate -/// // to the DefaultAssetBundle, MediaQuery, etc, which that method uses. -/// _getPicture(); -/// } -/// -/// @override -/// void didUpdateWidget(MyPicture oldWidget) { -/// super.didUpdateWidget(oldWidget); -/// if (widget.PictureProvider != oldWidget.PictureProvider) -/// _getPicture(); -/// } -/// -/// void _getPicture() { -/// final PictureStream oldPictureStream = _PictureStream; -/// _PictureStream = widget.PictureProvider.resolve(createLocalPictureConfiguration(context)); -/// if (_PictureStream.key != oldPictureStream?.key) { -/// // If the keys are the same, then we got the same picture back, and so we don't -/// // need to update the listeners. If the key changed, though, we must make sure -/// // to switch our listeners to the new picture stream. -/// oldPictureStream?.removeListener(_updatePicture); -/// _PictureStream.addListener(_updatePicture); -/// } -/// } -/// -/// void _updatePicture(PictureInfo pictureInfo, bool synchronousCall) { -/// setState(() { -/// // Trigger a build whenever the picture changes. -/// _pictureInfo = pictureInfo; -/// }); -/// } -/// -/// @override -/// void dispose() { -/// _PictureStream.removeListener(_updatePicture); -/// super.dispose(); -/// } -/// -/// @override -/// Widget build(BuildContext context) { -/// return RawPicture( -/// picture: _pictureInfo?.picture, // this is a dart:ui Picture object -/// scale: _pictureInfo?.scale ?? 1.0, -/// ); -/// } -/// } -/// ``` -@optionalTypeArgs -abstract class PictureProvider { - /// Abstract const constructor. This constructor enables subclasses to provide - /// const constructors so that they can be used in const expressions. - PictureProvider(this.colorFilter, {required this.decoderBuilder}) - : _theme = const SvgTheme(), - decoder = decoderBuilder(const SvgTheme()); - - /// The decoder builder to build a [decoder] when [theme] changes. - final PictureInfoDecoderBuilder decoderBuilder; - - /// The [PictureInfoDecoder] to use for loading this picture. - PictureInfoDecoder decoder; - - /// The [PictureCache] for [Picture] objects created by [PictureProvider] - /// implementations. - static final PictureCache cache = PictureCache(); - - /// The number of items in the [cache]. - @Deprecated('Use the `cache` object directly instead.') - static int get cacheCount => cache.count; - - /// Clears the [cache]. - @Deprecated('Use the `cache` object directly instead.') - static void clearCache() => cache.clear(); - - /// The color filter to apply to the picture, if any. - final ColorFilter? colorFilter; - - /// The default theme used when parsing SVG elements. - SvgTheme get theme => _theme; - SvgTheme _theme; - - /// Sets the [_theme] to [theme]. - /// - /// A theme is used when parsing SVG elements. Changing the theme - /// rebuilds a [decoder] using [decoderBuilder] and the new theme. - /// This will make the decoded SVG picture use properties from - /// the new theme. - set theme(SvgTheme value) { - if (_theme == value) { - return; - } - - if (_lastKey != null) { - cache.maybeEvict(_lastKey!, _theme, value); - _lastKey = null; - } - - decoder = decoderBuilder(value); - _theme = value; - } - - T? _lastKey; - - /// Resolves this Picture provider using the given `configuration`, returning - /// an [PictureStream]. - /// - /// This is the public entry-point of the [PictureProvider] class hierarchy. - /// - /// Subclasses should implement [obtainKey] and [load], which are used by this - /// method. - PictureStream resolve(PictureConfiguration picture, - {PictureErrorListener? onError}) { - // ignore: unnecessary_null_comparison - assert(picture != null); - final PictureStream stream = PictureStream(); - obtainKey(picture).then( - (T key) { - _lastKey = key; - stream.setCompleter( - cache.putIfAbsent( - key!, - () => load(key, onError: onError), - ), - ); - }, - ).catchError((Object exception, StackTrace stack) async { - if (onError != null) { - onError(exception, stack); - return; - } - FlutterError.reportError(FlutterErrorDetails( - exception: exception, - stack: stack, - library: 'SVG', - context: ErrorDescription('while resolving a picture'), - silent: true, // could be a network error or whatnot - informationCollector: () => [ - DiagnosticsProperty('Picture provider', this), - DiagnosticsProperty('Picture key', _lastKey, defaultValue: null), - ], - )); - }); - return stream; - } - - /// Converts a pictureProvider's settings plus a pictureConfiguration to a key - /// that describes the precise picture to load. - /// - /// The type of the key is determined by the subclass. It is a value that - /// unambiguously identifies the picture (_including its scale_) that the [load] - /// method will fetch. Different [PictureProvider]s given the same constructor - /// arguments and [PictureConfiguration] objects should return keys that are - /// '==' to each other (possibly by using a class for the key that itself - /// implements [==]). - Future obtainKey(PictureConfiguration picture); - - /// Converts a key into an [PictureStreamCompleter], and begins fetching the - /// picture. - @protected - PictureStreamCompleter load(T key, {PictureErrorListener? onError}); - - @override - String toString() => '$runtimeType()'; -} - -/// An immutable key representing the current state of a [PictureProvider]. -@immutable -class PictureKey { - /// Creates a new immutable key representing the current state of a - /// [PictureProvider] for the [PictureCache]. - const PictureKey( - this.keyData, { - required this.colorFilter, - required this.theme, - }); - - /// Some unique identifier for the source of this picture, e.g. a file name or - /// URL. - /// - /// If this is an iterable, it is assumed that the iterable will not be - /// modified after creating this object. - final T keyData; - - /// The color filter applied when this key was created. - final ColorFilter? colorFilter; - - /// The theme used when this key was created. - final SvgTheme theme; - - @override - bool operator ==(dynamic other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is PictureKey && - keyData == other.keyData && - colorFilter == other.colorFilter && - theme == other.theme; - } - - @override - int get hashCode => Object.hash(keyData.hashCode, colorFilter, theme); - - @override - String toString() => - 'PictureKey($keyData, colorFilter: $colorFilter, theme: $theme)'; -} - -/// Key for the picture obtained by an [AssetPicture] or [ExactAssetPicture]. -/// -/// This is used to identify the precise resource in the [pictureCache]. -@immutable -class AssetBundlePictureKey extends PictureKey { - /// Creates the key for an [AssetPicture] or [AssetBundlePictureProvider]. - /// - /// The arguments must not be null. - const AssetBundlePictureKey({ - required this.bundle, - required String name, - ColorFilter? colorFilter, - required SvgTheme theme, - }) : assert(bundle != null), // ignore: unnecessary_null_comparison - assert(name != null), // ignore: unnecessary_null_comparison - super(name, colorFilter: colorFilter, theme: theme); - - /// The bundle from which the picture will be obtained. - /// - /// The picture is obtained by calling [AssetBundle.load] on the given [bundle] - /// using the key given by [name]. - final AssetBundle bundle; - - /// The key to use to obtain the resource from the [bundle]. This is the - /// argument passed to [AssetBundle.load]. - String get name => keyData; - - @override - bool operator ==(dynamic other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is AssetBundlePictureKey && - bundle == other.bundle && - name == other.name && - colorFilter == other.colorFilter && - theme == other.theme; - } - - @override - int get hashCode => Object.hash(bundle, name, colorFilter, theme); - - @override - String toString() => - '$runtimeType(bundle: $bundle, name: "$name", colorFilter: $colorFilter, theme: $theme)'; -} - -/// A subclass of [PictureProvider] that knows about [AssetBundle]s. -/// -/// This factors out the common logic of [AssetBundle]-based [PictureProvider] -/// classes, simplifying what subclasses must implement to just [obtainKey]. -abstract class AssetBundlePictureProvider - extends PictureProvider { - /// Abstract const constructor. This constructor enables subclasses to provide - /// const constructors so that they can be used in const expressions. - AssetBundlePictureProvider(PictureInfoDecoderBuilder decoderBuilder, - ColorFilter? colorFilter) - : assert(decoderBuilder != null), // ignore: unnecessary_null_comparison - super(colorFilter, decoderBuilder: decoderBuilder); - - /// Converts a key into an [PictureStreamCompleter], and begins fetching the - /// picture using [_loadAsync]. - @override - PictureStreamCompleter load(AssetBundlePictureKey key, - {PictureErrorListener? onError}) { - return OneFramePictureStreamCompleter( - _loadAsync(key, onError), - informationCollector: () => [ - DiagnosticsProperty('Picture provider', this), - DiagnosticsProperty('Picture key', key), - ], - ); - } - - /// Fetches the picture from the asset bundle, decodes it, and returns a - /// corresponding [PictureInfo] object. - /// - /// This function is used by [load]. - @protected - Future _loadAsync( - AssetBundlePictureKey key, PictureErrorListener? onError) async { - final String data = await key.bundle.loadString(key.name); - - if (onError != null) { - return decoder( - data, - key.colorFilter, - key.toString(), - ).catchError((Object error, StackTrace stack) { - onError(error, stack); - return Future.error(error, stack); - }); - } - return decoder(data, key.colorFilter, key.toString()); - } -} - -/// The [PictureKey.keyData] for a [NetworkPicture]. -@immutable -class NetworkPictureKeyData { - /// Creates [PictureKey.keyData] for a [NetworkPicture]. - const NetworkPictureKeyData({required this.url, required this.headers}); - - /// The URL to request. - final String url; - - /// The headers include in the GET request to [url]. - final Map? headers; - - @override - bool operator ==(dynamic other) { - if (other.runtimeType != runtimeType) { - return false; - } - return other is NetworkPictureKeyData && - other.url == url && - other.headers == headers; - } - - @override - int get hashCode => Object.hash(url, headers); -} - -/// Fetches the given URL from the network, associating it with the given scale. -/// -/// The picture will be cached regardless of cache headers from the server. -/// -/// See also: -/// -/// * [SvgPicture.network] for a shorthand of an [SvgPicture] widget backed by [NetworkPicture]. -// TODO(ianh): Find some way to honour cache headers to the extent that when the -// last reference to a picture is released, we proactively evict the picture from -// our cache if the headers describe the picture as having expired at that point. -class NetworkPicture - extends PictureProvider, Uint8List> { - /// Creates an object that fetches the picture at the given URL. - /// - /// The arguments must not be null. - NetworkPicture(PictureInfoDecoderBuilder decoderBuilder, this.url, - {this.headers, ColorFilter? colorFilter}) - : assert(url != null), // ignore: unnecessary_null_comparison - super(colorFilter, decoderBuilder: decoderBuilder); - - /// The URL from which the picture will be fetched. - final String url; - - /// The HTTP headers that will be used with [HttpClient.get] to fetch picture from network. - final Map? headers; - - @override - Future> obtainKey( - PictureConfiguration picture) { - return SynchronousFuture>( - PictureKey( - NetworkPictureKeyData(url: url, headers: headers), - colorFilter: colorFilter, - theme: theme, - ), - ); - } - - @override - PictureStreamCompleter load(PictureKey key, - {PictureErrorListener? onError}) { - return OneFramePictureStreamCompleter( - _loadAsync(key, onError: onError), - informationCollector: () => [ - DiagnosticsProperty('Picture provider', this), - DiagnosticsProperty>( - 'Picture key', key), - ], - ); - } - - Future _loadAsync(PictureKey key, - {PictureErrorListener? onError}) async { - assert(url == key.keyData.url); - assert(headers == key.keyData.headers); - final Uint8List bytes = await httpGet(url, headers: headers); - - if (onError != null) { - return decoder( - bytes, - colorFilter, - key.toString(), - ).catchError((Object error, StackTrace stack) { - onError(error, stack); - return Future.error(error, stack); - }); - } - return decoder(bytes, colorFilter, key.toString()); - } - - @override - String toString() => - '$runtimeType("$url", headers: $headers, colorFilter: $colorFilter)'; -} - -/// Decodes the given [File] object as a picture, associating it with the given -/// scale. -/// -/// See also: -/// -/// * [SvgPicture.file] for a shorthand of an [SvgPicture] widget backed by [FilePicture]. -class FilePicture extends PictureProvider, Uint8List> { - /// Creates an object that decodes a [File] as a picture. - /// - /// The arguments must not be null. - FilePicture(PictureInfoDecoderBuilder decoderBuilder, this.file, - {ColorFilter? colorFilter}) - : assert(decoderBuilder != null), // ignore: unnecessary_null_comparison - assert(file != null), // ignore: unnecessary_null_comparison - super(colorFilter, decoderBuilder: decoderBuilder); - - /// The file to decode into a picture. - final File file; - - @override - Future> obtainKey(PictureConfiguration picture) { - return SynchronousFuture>( - PictureKey( - file.path, - colorFilter: colorFilter, - theme: theme, - ), - ); - } - - @override - PictureStreamCompleter load(PictureKey key, - {PictureErrorListener? onError}) { - return OneFramePictureStreamCompleter( - _loadAsync(key, onError: onError), - informationCollector: () => [ - DiagnosticsProperty('Path', file.path), - ], - ); - } - - Future _loadAsync(PictureKey key, - {PictureErrorListener? onError}) async { - assert(key.keyData == file.path); - - final Uint8List data = await file.readAsBytes(); - if (data.isEmpty) { - return null; - } - if (onError != null) { - return decoder( - data, - colorFilter, - key.toString(), - ).catchError((Object error, StackTrace stack) async { - onError(error, stack); - return Future.error(error, stack); - }); - } - return decoder(data, colorFilter, key.toString()); - } - - @override - String toString() => - '$runtimeType("${file.path}", colorFilter: $colorFilter)'; -} - -/// Decodes the given [String] buffer as a picture, associating it with the -/// given scale. -/// -/// The provided [bytes] buffer should not be changed after it is provided -/// to a [MemoryPicture]. To provide an [PictureStream] that represents a picture -/// that changes over time, consider creating a new subclass of [PictureProvider] -/// whose [load] method returns a subclass of [PictureStreamCompleter] that can -/// handle providing multiple pictures. -/// -/// See also: -/// -/// * [SvgPicture.memory] for a shorthand of an [SvgPicture] widget backed by [MemoryPicture]. -class MemoryPicture extends PictureProvider, Uint8List> { - /// Creates an object that decodes a [Uint8List] buffer as a picture. - /// - /// The arguments must not be null. - MemoryPicture(PictureInfoDecoderBuilder decoderBuilder, this.bytes, - {ColorFilter? colorFilter}) - : assert(bytes != null), // ignore: unnecessary_null_comparison - super(colorFilter, decoderBuilder: decoderBuilder); - - /// The bytes to decode into a picture. - final Uint8List bytes; - - @override - Future> obtainKey(PictureConfiguration picture) { - return SynchronousFuture>( - PictureKey( - bytes, - colorFilter: colorFilter, - theme: theme, - ), - ); - } - - @override - PictureStreamCompleter load(PictureKey key, - {PictureErrorListener? onError}) { - return OneFramePictureStreamCompleter(_loadAsync(key, onError: onError)); - } - - Future _loadAsync(PictureKey key, - {PictureErrorListener? onError}) async { - assert(key.keyData == bytes); - if (onError != null) { - return decoder( - bytes, - colorFilter, - key.toString(), - ).catchError((Object error, StackTrace stack) { - onError(error, stack); - return Future.error(error, stack); - }); - } - return decoder(bytes, colorFilter, key.toString()); - } - - @override - String toString() => '$runtimeType(${describeIdentity(bytes)})'; -} - -/// Decodes the given [String] as a picture, associating it with the -/// given scale. -/// -/// The provided [String] should not be changed after it is provided -/// to a [StringPicture]. To provide an [PictureStream] that represents a picture -/// that changes over time, consider creating a new subclass of [PictureProvider] -/// whose [load] method returns a subclass of [PictureStreamCompleter] that can -/// handle providing multiple pictures. -/// -/// See also: -/// -/// * [SvgPicture.string] for a shorthand of an [SvgPicture] widget backed by [StringPicture]. -class StringPicture extends PictureProvider, String> { - /// Creates an object that decodes a [Uint8List] buffer as a picture. - /// - /// The arguments must not be null. - StringPicture(PictureInfoDecoderBuilder decoderBuilder, this.string, - {ColorFilter? colorFilter}) - : assert(string != null), // ignore: unnecessary_null_comparison - super(colorFilter, decoderBuilder: decoderBuilder); - - /// The string to decode into a picture. - final String string; - - @override - Future> obtainKey(PictureConfiguration picture) { - return SynchronousFuture>( - PictureKey( - string, - colorFilter: colorFilter, - theme: theme, - ), - ); - } - - @override - PictureStreamCompleter load(PictureKey key, - {PictureErrorListener? onError}) { - return OneFramePictureStreamCompleter(_loadAsync(key, onError: onError)); - } - - Future _loadAsync( - PictureKey key, { - PictureErrorListener? onError, - }) { - assert(key.keyData == string); - if (onError != null) { - return decoder( - string, - colorFilter, - key.toString(), - ).catchError((Object error, StackTrace stack) { - onError(error, stack); - return Future.error(error, stack); - }); - } - return decoder(string, colorFilter, key.toString()); - } - - @override - String toString() => - '$runtimeType(${describeIdentity(string)}, colorFilter: $colorFilter)'; -} - -/// Fetches a picture from an [AssetBundle], associating it with the given scale. -/// -/// This implementation requires an explicit final [assetName] and [scale] on -/// construction, and ignores the device pixel ratio and size in the -/// configuration passed into [resolve]. For a resolution-aware variant that -/// uses the configuration to pick an appropriate picture based on the device -/// pixel ratio and size, see [AssetPicture]. -/// -/// ## Fetching assets -/// -/// When fetching a picture provided by the app itself, use the [assetName] -/// argument to name the asset to choose. For instance, consider a directory -/// `icons` with a picture `heart.png`. First, the [pubspec.yaml] of the project -/// should specify its assets in the `flutter` section: -/// -/// ```yaml -/// flutter: -/// assets: -/// - icons/heart.png -/// ``` -/// -/// Then, to fetch the picture and associate it with scale `1.5`, use -/// -/// ```dart -/// AssetPicture('icons/heart.png', scale: 1.5) -/// ``` -/// -///## Assets in packages -/// -/// To fetch an asset from a package, the [package] argument must be provided. -/// For instance, suppose the structure above is inside a package called -/// `my_icons`. Then to fetch the picture, use: -/// -/// ```dart -/// AssetPicture('icons/heart.png', scale: 1.5, package: 'my_icons') -/// ``` -/// -/// Assets used by the package itself should also be fetched using the [package] -/// argument as above. -/// -/// If the desired asset is specified in the `pubspec.yaml` of the package, it -/// is bundled automatically with the app. In particular, assets used by the -/// package itself must be specified in its `pubspec.yaml`. -/// -/// A package can also choose to have assets in its 'lib/' folder that are not -/// specified in its `pubspec.yaml`. In this case for those pictures to be -/// bundled, the app has to specify which ones to include. For instance a -/// package named `fancy_backgrounds` could have: -/// -/// ``` -/// lib/backgrounds/background1.png -/// lib/backgrounds/background2.png -/// lib/backgrounds/background3.png -///``` -/// -/// To include, say the first picture, the `pubspec.yaml` of the app should specify -/// it in the `assets` section: -/// -/// ```yaml -/// assets: -/// - packages/fancy_backgrounds/backgrounds/background1.png -/// ``` -/// -/// Note that the `lib/` is implied, so it should not be included in the asset -/// path. -/// -/// See also: -/// -/// * [SvgPicture.asset] for a shorthand of an [SvgPicture] widget backed by -/// [ExactAssetPicture] when using a scale. -class ExactAssetPicture extends AssetBundlePictureProvider { - /// Creates an object that fetches the given picture from an asset bundle. - /// - /// The [assetName] and [scale] arguments must not be null. The [scale] arguments - /// defaults to 1.0. The [bundle] argument may be null, in which case the - /// bundle provided in the [PictureConfiguration] passed to the [resolve] call - /// will be used instead. - /// - /// The [package] argument must be non-null when fetching an asset that is - /// included in a package. See the documentation for the [ExactAssetPicture] class - /// itself for details. - ExactAssetPicture( - PictureInfoDecoderBuilder decoderBuilder, - this.assetName, { - this.bundle, - this.package, - ColorFilter? colorFilter, - }) : assert(assetName != null), // ignore: unnecessary_null_comparison - super(decoderBuilder, colorFilter); - - /// The name of the asset. - final String assetName; - - /// The key to use to obtain the resource from the [bundle]. This is the - /// argument passed to [AssetBundle.load]. - String get keyName => - package == null ? assetName : 'packages/$package/$assetName'; - - /// The bundle from which the picture will be obtained. - /// - /// If the provided [bundle] is null, the bundle provided in the - /// [PictureConfiguration] passed to the [resolve] call will be used instead. If - /// that is also null, the [rootBundle] is used. - /// - /// The picture is obtained by calling [AssetBundle.load] on the given [bundle] - /// using the key given by [keyName]. - final AssetBundle? bundle; - - /// The name of the package from which the picture is included. See the - /// documentation for the [ExactAssetPicture] class itself for details. - final String? package; - - @override - Future obtainKey(PictureConfiguration picture) { - return SynchronousFuture( - AssetBundlePictureKey( - bundle: bundle ?? picture.bundle ?? rootBundle, - name: keyName, - colorFilter: colorFilter, - theme: theme, - ), - ); - } - - @override - String toString() => - '$runtimeType(name: "$keyName", bundle: $bundle, colorFilter: $colorFilter)'; -} diff --git a/third_party/lib/src/picture_stream.dart b/third_party/lib/src/picture_stream.dart deleted file mode 100644 index e2cb74e5c613..000000000000 --- a/third_party/lib/src/picture_stream.dart +++ /dev/null @@ -1,442 +0,0 @@ -// Copyright 2015 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:async'; -import 'dart:ui' show Picture, Rect, Size; - -import 'package:flutter/foundation.dart'; -import 'package:flutter/rendering.dart'; -import 'package:flutter_svg/flutter_svg.dart'; - -/// The signature of a method that listens for errors on picture stream resolution. -typedef PictureErrorListener = void Function( - Object exception, - StackTrace stackTrace, -); - -@immutable -class _PictureListenerPair { - const _PictureListenerPair(this.listener, this.errorListener); - final PictureListener listener; - final PictureErrorListener? errorListener; -} - -/// Represents information about a ui.Picture to be drawn on a canvas. -class PictureInfo { - /// Creates a new PictureInfo object. - PictureInfo({ - required Picture picture, - required this.viewport, - this.size = Size.infinite, - required this.compatibilityTester, - }) : assert(picture != null), // ignore: unnecessary_null_comparison - assert(viewport != null), // ignore: unnecessary_null_comparison - assert(size != null), // ignore: unnecessary_null_comparison - _picture = picture; - - /// The raw picture. - /// - /// This picture's lifecycle will be managed by the provider. It will be - /// reused as long as the picture does not change, and disposed when the - /// provider loses all of its listeners or it is unset. Once it has been - /// disposed, it will return null. - Picture? get picture => _picture; - Picture? _picture; - - /// The viewport enclosing the coordinates used in the picture. - final Rect viewport; - - /// The requested size for this picture, which may be different than the - /// [viewport.size]. - final Size size; - - /// A tester for whether ambienty property changes should invalidate the cache - /// for the [Picture]. - final CacheCompatibilityTester compatibilityTester; - - /// Creates a [PictureLayer] that will suitably manage the lifecycle of the - /// [picture]. - /// - /// This must not be called if all created handles have been disposed. - PictureLayer createLayer() { - assert(picture != null); - return _NonOwningComplexPictureLayer(this); - } - - final Set _handles = {}; - - /// Returns the number of open picture handles on this picture info. - /// - /// Outside of debug mode, this returns null. - int? get debugHandleCount { - if (kDebugMode) { - return _handles.length; - } - return null; - } - - /// Creates a [PictureHandle] that keeps the [picture] from being disposed. - /// - /// Once all created handles are disposed, the underlying [picture] must not - /// be used again. - PictureHandle createHandle() { - final PictureHandle handle = PictureHandle._(this); - _handles.add(handle._id); - return handle; - } - - void _disposeHandle(PictureHandle handle) { - assert(_handles.isNotEmpty); - assert(_picture != null); - final bool removed = _handles.remove(handle._id); - assert(removed); - if (_handles.isEmpty) { - _picture!.dispose(); - _picture = null; - } - } -} - -/// An opaque handle used by [PictureInfo] to track the lifecycle of a -/// [Picture]. -/// -/// Create handles using [PictureInfo.createHandle]. Dispose of them using -/// [dispose]. -@immutable -class PictureHandle { - PictureHandle._(this._owner); - - static int _counter = 1; - final int _id = _counter++; - - final PictureInfo _owner; - - /// Disposes of this handle. Must not be called more than once. - void dispose() { - _owner._disposeHandle(this); - } - - @override - int get hashCode => _id; - - @override - bool operator ==(Object other) { - return other is PictureHandle && other._id == _id; - } -} - -/// Signature for callbacks reporting that an image is available. -/// -/// Used by [PictureStream]. -/// -/// The `synchronousCall` argument is true if the listener is being invoked -/// during the call to addListener. This can be useful if, for example, -/// [PictureStream.addListener] is invoked during a frame, so that a new rendering -/// frame is requested if the call was asynchronous (after the current frame) -/// and no rendering frame is requested if the call was synchronous (within the -/// same stack frame as the call to [PictureStream.addListener]). -typedef PictureListener = Function(PictureInfo? image, bool synchronousCall); - -/// A handle to an image resource. -/// -/// PictureStream represents a handle to a [dart:ui.Image] object and its scale -/// (together represented by an [ImageInfo] object). The underlying image object -/// might change over time, either because the image is animating or because the -/// underlying image resource was mutated. -/// -/// PictureStream objects can also represent an image that hasn't finished -/// loading. -/// -/// PictureStream objects are backed by [PictureStreamCompleter] objects. -/// -/// See also: -/// -/// * [PictureProvider], which has an example that includes the use of an -/// [PictureStream] in a [Widget]. -class PictureStream with Diagnosticable { - /// Create an initially unbound image stream. - /// - /// Once an [PictureStreamCompleter] is available, call [setCompleter]. - PictureStream(); - - /// The completer that has been assigned to this image stream. - /// - /// Generally there is no need to deal with the completer directly. - PictureStreamCompleter? get completer => _completer; - PictureStreamCompleter? _completer; - - List<_PictureListenerPair>? _listeners; - - /// Assigns a particular [PictureStreamCompleter] to this [PictureStream]. - /// - /// This is usually done automatically by the [PictureProvider] that created the - /// [PictureStream]. - /// - /// This method can only be called once per stream. To have an [PictureStream] - /// represent multiple images over time, assign it a completer that - /// completes several images in succession. - void setCompleter(PictureStreamCompleter value) { - assert(_completer == null); - _completer = value; - if (_listeners != null) { - final List<_PictureListenerPair> initialListeners = _listeners!; - _listeners = null; - for (_PictureListenerPair pair in initialListeners) { - _completer!.addListener(pair.listener, onError: pair.errorListener); - } - } - } - - /// Adds a listener callback that is called whenever a new concrete [ImageInfo] - /// object is available. If a concrete image is already available, this object - /// will call the listener synchronously. - /// - /// If the assigned [completer] completes multiple images over its lifetime, - /// this listener will fire multiple times. - /// - /// The listener will be passed a flag indicating whether a synchronous call - /// occurred. If the listener is added within a render object paint function, - /// then use this flag to avoid calling [RenderObject.markNeedsPaint] during - /// a paint. - void addListener(PictureListener listener, {PictureErrorListener? onError}) { - if (_completer != null) { - return _completer!.addListener(listener, onError: onError); - } - _listeners ??= <_PictureListenerPair>[]; - _listeners!.add(_PictureListenerPair(listener, onError)); - } - - /// Stop listening for new concrete [PictureInfo] objects. - void removeListener(PictureListener listener) { - if (_completer != null) { - return _completer!.removeListener(listener); - } - assert(_listeners != null); - _listeners!.removeWhere( - (_PictureListenerPair pair) => pair.listener == listener, - ); - } - - /// Returns an object which can be used with `==` to determine if this - /// [PictureStream] shares the same listeners list as another [PictureStream]. - /// - /// This can be used to avoid unregistering and reregistering listeners after - /// calling [PictureProvider.resolve] on a new, but possibly equivalent, - /// [PictureProvider]. - /// - /// The key may change once in the lifetime of the object. When it changes, it - /// will go from being different than other [PictureStream]'s keys to - /// potentially being the same as others'. No notification is sent when this - /// happens. - Object? get key => _completer != null ? _completer : this; - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties.add(ObjectFlagProperty( - 'completer', - _completer, - ifPresent: _completer?.toStringShort(), - ifNull: 'unresolved', - )); - properties.add(ObjectFlagProperty>( - 'listeners', - _listeners, - ifPresent: - '${_listeners?.length} listener${_listeners?.length == 1 ? "" : "s"}', - ifNull: 'no listeners', - level: _completer != null ? DiagnosticLevel.hidden : DiagnosticLevel.info, - )); - _completer?.debugFillProperties(properties); - } -} - -/// Base class for those that manage the loading of [dart:ui.Picture] objects for -/// [PictureStream]s. -/// -/// [PictureStreamListener] objects are rarely constructed directly. Generally, an -/// [PictureProvider] subclass will return an [PictureStream] and automatically -/// configure it with the right [PictureStreamCompleter] when possible. -abstract class PictureStreamCompleter with Diagnosticable { - final List<_PictureListenerPair> _listeners = <_PictureListenerPair>[]; - PictureInfo? _current; - PictureHandle? _handle; - - bool _cached = false; - - /// Whether or not this completer is in the [PictureCache]. - bool get cached => _cached; - set cached(bool value) { - if (value == _cached) { - return; - } - if (!value && _listeners.isEmpty) { - _handle?.dispose(); - _handle = null; - _current = null; - } - _cached = value; - } - - /// Adds a listener callback that is called whenever a new concrete [PictureInfo] - /// object is available. If a concrete image is already available, this object - /// will call the listener synchronously. - /// - /// If the [PictureStreamCompleter] completes multiple images over its lifetime, - /// this listener will fire multiple times. - /// - /// The listener will be passed a flag indicating whether a synchronous call - /// occurred. If the listener is added within a render object paint function, - /// then use this flag to avoid calling [RenderObject.markNeedsPaint] during - /// a paint. - void addListener(PictureListener listener, {PictureErrorListener? onError}) { - _listeners.add(_PictureListenerPair(listener, onError)); - if (_current != null) { - try { - listener(_current, true); - } catch (exception, stack) { - _handleImageError( - ErrorDescription('by a synchronously-called image listener'), - exception, - stack, - ); - } - } - } - - /// Stop listening for new concrete [PictureInfo] objects. - void removeListener(PictureListener listener) { - _listeners.removeWhere( - (_PictureListenerPair pair) => pair.listener == listener, - ); - if (_listeners.isEmpty && !cached) { - _handle?.dispose(); - _current = null; - _handle = null; - } - } - - /// Tests whether the currently set [PictureInfo], if any, is compatible for - /// the given theme change. - bool isCompatible(SvgTheme oldData, SvgTheme newData) { - return _current?.compatibilityTester.isCompatible(oldData, newData) ?? true; - } - - /// Calls all the registered listeners to notify them of a new picture. - @protected - void setPicture(PictureInfo? picture) { - _handle?.dispose(); - _current = picture; - _handle = _current?.createHandle(); - if (_listeners.isEmpty) { - return; - } - final List<_PictureListenerPair> localListeners = - List<_PictureListenerPair>.from(_listeners); - for (_PictureListenerPair listenerPair in localListeners) { - try { - listenerPair.listener(picture, false); - } catch (exception, stack) { - if (listenerPair.errorListener != null) { - listenerPair.errorListener!(exception, stack); - } else { - _handleImageError( - ErrorDescription('by a picture listener'), - exception, - stack, - ); - } - } - } - } - - void _handleImageError( - DiagnosticsNode context, - Object exception, - dynamic stack, - ) { - FlutterError.reportError(FlutterErrorDetails( - exception: exception, - stack: stack as StackTrace, - library: 'SVG', - context: context, - )); - } - - @override - void debugFillProperties(DiagnosticPropertiesBuilder properties) { - super.debugFillProperties(properties); - properties.add(DiagnosticsProperty('current', _current, - ifNull: 'unresolved', showName: false)); - properties.add(ObjectFlagProperty>( - 'listeners', - _listeners, - ifPresent: - '${_listeners.length} listener${_listeners.length == 1 ? "" : "s"}', - )); - properties.add(FlagProperty('cached', value: cached, ifTrue: 'cached')); - } -} - -/// Manages the loading of [dart:ui.Picture] objects for static [PictureStream]s (those -/// with only one frame). -class OneFramePictureStreamCompleter extends PictureStreamCompleter { - /// Creates a manager for one-frame [PictureStream]s. - /// - /// The image resource awaits the given [Future]. When the future resolves, - /// it notifies the [PictureListener]s that have been registered with - /// [addListener]. - /// - /// The [InformationCollector], if provided, is invoked if the given [Future] - /// resolves with an error, and can be used to supplement the reported error - /// message (for example, giving the image's URL). - /// - /// Errors are reported using [FlutterError.reportError] with the `silent` - /// argument on [FlutterErrorDetails] set to true, meaning that by default the - /// message is only dumped to the console in debug mode (see [FlutterErrorDetails]). - OneFramePictureStreamCompleter( - Future picture, { - InformationCollector? informationCollector, - // ignore: unnecessary_null_comparison - }) : assert(picture != null) { - picture.then(setPicture, onError: (Object error, StackTrace stack) { - FlutterError.reportError(FlutterErrorDetails( - exception: error, - stack: stack, - library: 'SVG', - context: ErrorDescription('resolving a single-frame picture stream'), - informationCollector: informationCollector, - silent: true, - )); - }); - } -} - -class _NonOwningComplexPictureLayer extends PictureLayer { - _NonOwningComplexPictureLayer(this._owner) - : _handle = _owner.createHandle(), - super(_owner.viewport); - - final PictureInfo _owner; - PictureHandle? _handle; - - @override - bool get isComplexHint => true; - - @override - Picture? get picture => _owner.picture; - - @override - set picture(Picture? picture) { - // Should only get called from dispose. - assert(picture == null); - assert(_handle != null); - if (picture != null) { - markNeedsAddToScene(); - } else { - _handle?.dispose(); - _handle = null; - } - } -} diff --git a/third_party/lib/src/render_picture.dart b/third_party/lib/src/render_picture.dart deleted file mode 100644 index a72b7b5650f9..000000000000 --- a/third_party/lib/src/render_picture.dart +++ /dev/null @@ -1,291 +0,0 @@ -import 'dart:math' as math; - -import 'package:flutter/rendering.dart'; -import 'package:flutter/widgets.dart'; - -import 'picture_stream.dart'; - -/// A widget that displays a [dart:ui.Picture] directly. -@immutable -class RawPicture extends LeafRenderObjectWidget { - /// Creates a new [RawPicture] object. - const RawPicture( - this.picture, { - Key? key, - this.matchTextDirection = false, - this.allowDrawingOutsideViewBox = false, - }) : super(key: key); - - /// The picture to paint. - final PictureInfo? picture; - - /// Whether this picture should match the ambient [TextDirection] or not. - final bool matchTextDirection; - - /// Whether to allow this picture to draw outside of its specified - /// [PictureInfo.viewport]. Caution should be used here, as this may lead to - /// greater memory usage than intended. - final bool allowDrawingOutsideViewBox; - - @override - RenderPicture createRenderObject(BuildContext context) { - return RenderPicture( - picture: picture, - matchTextDirection: matchTextDirection, - textDirection: matchTextDirection ? Directionality.of(context) : null, - allowDrawingOutsideViewBox: allowDrawingOutsideViewBox, - ); - } - - @override - void updateRenderObject(BuildContext context, RenderPicture renderObject) { - renderObject - ..picture = picture - ..matchTextDirection = matchTextDirection - ..allowDrawingOutsideViewBox = allowDrawingOutsideViewBox - ..textDirection = matchTextDirection ? Directionality.of(context) : null; - } -} - -/// A picture in the render tree. -/// -/// The render picture will draw based on its parents dimensions maintaining -/// its aspect ratio. -/// -/// If `matchTextDirection` is true, the picture will be flipped horizontally in -/// [TextDirection.rtl] contexts. If `allowDrawingOutsideViewBox` is true, the -/// picture will be allowed to draw beyond the constraints of its viewbox; this -/// flag should be used with care, as it may result in unexpected effects or -/// additional memory usage. -class RenderPicture extends RenderBox { - /// Creates a new [RenderPicture]. - RenderPicture({ - PictureInfo? picture, - bool matchTextDirection = false, - TextDirection? textDirection, - bool? allowDrawingOutsideViewBox, - }) : _matchTextDirection = matchTextDirection, - _textDirection = textDirection, - _allowDrawingOutsideViewBox = allowDrawingOutsideViewBox { - this.picture = picture; - } - - /// Optional color to use to draw a thin rectangle around the canvas. - /// - /// Only applied if asserts are enabled (e.g. debug mode). - static Color? debugRectColor; - - /// Whether to paint the picture in the direction of the [TextDirection]. - /// - /// If this is true, then in [TextDirection.ltr] contexts, the picture will be - /// drawn with its origin in the top left (the "normal" painting direction for - /// pictures); and in [TextDirection.rtl] contexts, the picture will be drawn with - /// a scaling factor of -1 in the horizontal direction so that the origin is - /// in the top right. - /// - /// This is occasionally used with pictures in right-to-left environments, for - /// pictures that were designed for left-to-right locales. Be careful, when - /// using this, to not flip pictures with integral shadows, text, or other - /// effects that will look incorrect when flipped. - /// - /// If this is set to true, [textDirection] must not be null. - bool get matchTextDirection => _matchTextDirection; - bool _matchTextDirection; - set matchTextDirection(bool value) { - assert(value != null); // ignore: unnecessary_null_comparison - if (value == _matchTextDirection) { - return; - } - _matchTextDirection = value; - markNeedsPaint(); - } - - bool get _flipHorizontally => - _matchTextDirection && _textDirection == TextDirection.rtl; - - /// The text direction with which to resolve [alignment]. - /// - /// This may be changed to null, but only after the [alignment] and - /// [matchTextDirection] properties have been changed to values that do not - /// depend on the direction. - TextDirection? get textDirection => _textDirection; - TextDirection? _textDirection; - set textDirection(TextDirection? value) { - if (_textDirection == value) { - return; - } - _textDirection = value; - markNeedsPaint(); - } - - /// The information about the picture to draw. - PictureInfo? get picture => _picture; - PictureInfo? _picture; - set picture(PictureInfo? value) { - // Don't use `==` because PictureInfo is mutable and it has values that are - // not relevant to rendering. - if (value != null && - value.picture == picture?.picture && - value.size == picture?.size && - value.viewport == picture?.viewport) { - return; - } - _picture = value; - _pictureHandle.layer = _picture?.createLayer(); - assert(() { - if (_pictureHandle.layer != null) { - assert(_pictureHandle.layer!.isComplexHint); - assert(!_pictureHandle.layer!.willChangeHint); - } - return true; - }()); - markNeedsPaint(); - } - - /// Whether to allow the rendering of this picture to exceed the - /// [PictureInfo.viewport] bounds. - /// - /// Caution should be used around setting this parameter to true, as it - /// may result in greater memory usage during rasterization. - bool? get allowDrawingOutsideViewBox => _allowDrawingOutsideViewBox; - bool? _allowDrawingOutsideViewBox; - set allowDrawingOutsideViewBox(bool? val) { - if (val == _allowDrawingOutsideViewBox) { - return; - } - - _allowDrawingOutsideViewBox = val; - markNeedsPaint(); - } - - @override - bool hitTestSelf(Offset position) => true; - - @override - bool get sizedByParent => true; - - @override - Size computeDryLayout(BoxConstraints constraints) { - return constraints.smallest; - } - - @override - bool get isRepaintBoundary => true; - - final LayerHandle _transformHandle = - LayerHandle(); - - final LayerHandle _clipHandle = LayerHandle(); - - final LayerHandle _pictureHandle = LayerHandle(); - - void _addPicture(PaintingContext context, Offset offset) { - assert(picture != null); - assert(_pictureHandle.layer != null); - if (allowDrawingOutsideViewBox != true) { - final Rect viewportRect = Offset.zero & _picture!.viewport.size; - _clipHandle.layer = context.pushClipRect( - needsCompositing, - offset, - viewportRect, - (PaintingContext context, Offset offset) { - context.addLayer(_pictureHandle.layer!); - }, - oldLayer: _clipHandle.layer, - ); - } else { - _clipHandle.layer = null; - context.addLayer(_pictureHandle.layer!); - } - } - - @override - void dispose() { - _transformHandle.layer = null; - _clipHandle.layer = null; - _pictureHandle.layer = null; - super.dispose(); - } - - @override - void paint(PaintingContext context, Offset offset) { - if (picture == null || size == Size.zero) { - return; - } - - bool needsTransform = false; - final Matrix4 transform = Matrix4.identity(); - - if (_flipHorizontally) { - needsTransform = true; - transform - ..translate(size.width, 0.0) - ..scale(-1.0, 1.0); - } - - if (scaleCanvasToViewBox( - transform, - size, - _picture!.viewport, - _picture!.size, - )) { - needsTransform = true; - } - - if (needsTransform) { - _transformHandle.layer = context.pushTransform( - needsCompositing, - offset, - transform, - _addPicture, - oldLayer: _transformHandle.layer, - ); - } else { - _transformHandle.layer = null; - _addPicture(context, offset); - } - - // this is sometimes useful for debugging, e.g. to draw - // a thin red border around the drawing. - assert(() { - if (RenderPicture.debugRectColor != null && - RenderPicture.debugRectColor!.alpha > 0) { - context.canvas.drawRect( - Offset.zero & size, - Paint() - ..color = debugRectColor! - ..style = PaintingStyle.stroke); - } - return true; - }()); - } -} - -/// Scales a matrix to the given [viewBox] based on the [desiredSize] -/// of the widget. -/// -/// Returns true if the supplied matrix was modified. -bool scaleCanvasToViewBox( - Matrix4 matrix, - Size desiredSize, - Rect viewBox, - Size pictureSize, -) { - if (desiredSize == viewBox.size) { - return false; - } - final double scale = math.min( - desiredSize.width / viewBox.width, - desiredSize.height / viewBox.height, - ); - final Size scaledHalfViewBoxSize = viewBox.size * scale / 2.0; - final Size halfDesiredSize = desiredSize / 2.0; - final Offset shift = Offset( - halfDesiredSize.width - scaledHalfViewBoxSize.width, - halfDesiredSize.height - scaledHalfViewBoxSize.height, - ); - matrix - ..translate(shift.dx, shift.dy) - ..scale(scale, scale); - return true; -} diff --git a/third_party/lib/src/svg/default_theme.dart b/third_party/lib/src/svg/default_theme.dart deleted file mode 100644 index e85cca7e271f..000000000000 --- a/third_party/lib/src/svg/default_theme.dart +++ /dev/null @@ -1,41 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_svg/src/svg/theme.dart'; - -/// The SVG theme to apply to descendant [SvgPicture] widgets -/// which don't have explicit theme values. -class DefaultSvgTheme extends InheritedTheme { - /// Creates a default SVG theme for the given subtree - /// using the provided [theme]. - const DefaultSvgTheme({ - Key? key, - required Widget child, - required this.theme, - }) : super(key: key, child: child); - - /// The SVG theme to apply. - final SvgTheme theme; - - /// The closest instance of this class that encloses the given context. - /// - /// Typical usage is as follows: - /// - /// ```dart - /// DefaultSvgTheme theme = DefaultSvgTheme.of(context); - /// ``` - static DefaultSvgTheme? of(BuildContext context) { - return context.dependOnInheritedWidgetOfExactType(); - } - - @override - bool updateShouldNotify(DefaultSvgTheme oldWidget) { - return theme != oldWidget.theme; - } - - @override - Widget wrap(BuildContext context, Widget child) { - return DefaultSvgTheme( - theme: theme, - child: child, - ); - } -} diff --git a/third_party/lib/src/svg/parser_state.dart b/third_party/lib/src/svg/parser_state.dart deleted file mode 100644 index e9a4a5e60472..000000000000 --- a/third_party/lib/src/svg/parser_state.dart +++ /dev/null @@ -1,1960 +0,0 @@ -import 'dart:collection'; -import 'dart:ui'; - -import 'package:flutter/foundation.dart'; -import 'package:path_drawing/path_drawing.dart'; -import 'package:vector_math/vector_math_64.dart'; -import 'package:xml/xml_events.dart' hide parseEvents; - -import '../svg/theme.dart'; -import '../utilities/errors.dart'; -import '../utilities/numbers.dart'; -import '../utilities/xml.dart'; -import '../vector_drawable.dart'; -import 'parsers.dart'; - -final Set _unhandledElements = {'title', 'desc'}; - -typedef _ParseFunc = Future? Function( - SvgParserState parserState, bool warningsAsErrors); -typedef _PathFunc = Path? Function(SvgParserState parserState); - -final RegExp _trimPattern = RegExp(r'[\r|\n|\t]'); - -const Map _svgElementParsers = { - 'svg': _Elements.svg, - 'g': _Elements.g, - 'a': _Elements.g, // treat as group - 'use': _Elements.use, - 'symbol': _Elements.symbol, - 'mask': _Elements.symbol, // treat as symbol - 'radialGradient': _Elements.radialGradient, - 'linearGradient': _Elements.linearGradient, - 'clipPath': _Elements.clipPath, - 'image': _Elements.image, - 'text': _Elements.text, -}; - -const Map _svgPathFuncs = { - 'circle': _Paths.circle, - 'path': _Paths.path, - 'rect': _Paths.rect, - 'polygon': _Paths.polygon, - 'polyline': _Paths.polyline, - 'ellipse': _Paths.ellipse, - 'line': _Paths.line, -}; - -Offset _parseCurrentOffset(SvgParserState parserState, Offset? lastOffset) { - final String? x = parserState.attribute('x', def: null); - final String? y = parserState.attribute('y', def: null); - - return Offset( - x != null - ? parserState.parseDoubleWithUnits(x)! - : parserState.parseDoubleWithUnits( - parserState.attribute('dx', def: '0'), - )! + - (lastOffset?.dx ?? 0), - y != null - ? parserState.parseDoubleWithUnits(y)! - : parserState.parseDoubleWithUnits( - parserState.attribute('dy', def: '0'), - )! + - (lastOffset?.dy ?? 0), - ); -} - -class _TextInfo { - const _TextInfo( - this.style, - this.offset, - this.transform, - ); - - final DrawableStyle style; - final Offset offset; - final Matrix4? transform; - - @override - String toString() => '$runtimeType{$offset, $style, $transform}'; -} - -// ignore: avoid_classes_with_only_static_members -class _Elements { - static Future? svg(SvgParserState parserState, bool warningsAsErrors) { - final DrawableViewport? viewBox = parserState.parseViewBox(); - - final String? id = parserState.attribute('id', def: ''); - - final Color? color = parserState.parseColor( - parserState.attribute('color', def: null), - currentColor: parserState.theme.currentColor, - ); - - // TODO(dnfield): Support nested SVG elements. https://github.com/dnfield/flutter_svg/issues/132 - if (parserState._root != null) { - const String errorMessage = 'Unsupported nested element.'; - if (warningsAsErrors) { - throw UnsupportedError(errorMessage); - } - FlutterError.reportError(FlutterErrorDetails( - exception: UnsupportedError(errorMessage), - informationCollector: () => [ - ErrorDescription( - 'The root element contained an unsupported nested SVG element.'), - if (parserState._key != null) ErrorDescription(''), - if (parserState._key != null) - DiagnosticsProperty('Picture key', parserState._key), - ], - library: 'SVG', - context: ErrorDescription('in _Element.svg'), - )); - - parserState._parentDrawables.addLast( - _SvgGroupTuple( - 'svg', - DrawableGroup( - id, - [], - parserState.parseStyle(viewBox!.viewBoxRect, null, - currentColor: color), - color: color, - ), - ), - ); - return null; - } - parserState._root = DrawableRoot( - id, - viewBox!, - [], - parserState._definitions, - parserState.parseStyle(viewBox.viewBoxRect, null, currentColor: color), - color: color, - compatibilityTester: parserState._compatibilityTester, - ); - parserState.addGroup(parserState._currentStartElement!, parserState._root); - return null; - } - - static Future? g(SvgParserState parserState, bool warningsAsErrors) { - if (parserState._currentStartElement?.isSelfClosing == true) { - return null; - } - final DrawableParent parent = parserState.currentGroup!; - final Color? color = parserState.parseColor( - parserState.attribute('color', def: null), - currentColor: parent.color ?? parserState.theme.currentColor) ?? - parent.color; - - final DrawableGroup group = DrawableGroup( - parserState.attribute('id', def: ''), - [], - parserState.parseStyle(parserState.rootBounds, parent.style, - currentColor: color), - transform: parseTransform(parserState.attribute('transform'))?.storage, - color: color, - ); - parent.children!.add(group); - parserState.addGroup(parserState._currentStartElement!, group); - return null; - } - - static Future? symbol( - SvgParserState parserState, bool warningsAsErrors) { - final DrawableParent parent = parserState.currentGroup!; - final Color? color = parserState.parseColor( - parserState.attribute('color', def: null), - currentColor: parent.color ?? parserState.theme.currentColor) ?? - parent.color; - - final DrawableGroup group = DrawableGroup( - parserState.attribute('id', def: ''), - [], - parserState.parseStyle( - parserState.rootBounds, - parent.style, - currentColor: color, - ), - transform: parseTransform(parserState.attribute('transform'))?.storage, - color: color, - ); - parserState.addGroup(parserState._currentStartElement!, group); - return null; - } - - static Future? use(SvgParserState parserState, bool warningsAsErrors) { - final DrawableParent? parent = parserState.currentGroup; - final String xlinkHref = getHrefAttribute(parserState.attributes)!; - if (xlinkHref.isEmpty) { - return null; - } - - final DrawableStyle style = parserState.parseStyle( - parserState.rootBounds, - parent!.style, - currentColor: parent.color, - ); - - final Matrix4 transform = - parseTransform(parserState.attribute('transform')) ?? - Matrix4.identity(); - transform.translate( - parserState.parseDoubleWithUnits( - parserState.attribute('x', def: '0'), - ), - parserState.parseDoubleWithUnits( - parserState.attribute('y', def: '0'), - )!, - ); - - final DrawableStyleable ref = - parserState._definitions.getDrawable('url($xlinkHref)')!; - final DrawableGroup group = DrawableGroup( - parserState.attribute('id', def: ''), - [ref.mergeStyle(style)], - style, - transform: transform.storage, - ); - parserState.checkForIri(group); - - parent.children!.add(group); - return null; - } - - static Future? parseStops( - SvgParserState parserState, - List colors, - List offsets, - ) { - final DrawableParent parent = parserState.currentGroup!; - - for (XmlEvent event in parserState._readSubtree()) { - if (event is XmlEndElementEvent) { - continue; - } - if (event is XmlStartElementEvent) { - final String rawOpacity = getAttribute( - parserState.attributes, - 'stop-opacity', - def: '1', - )!; - final Color stopColor = parserState.parseColor( - getAttribute(parserState.attributes, 'stop-color'), - currentColor: parent.color ?? parserState.theme.currentColor) ?? - parent.color ?? - colorBlack; - colors.add(stopColor.withOpacity(parseDouble(rawOpacity)!)); - - final String rawOffset = getAttribute( - parserState.attributes, - 'offset', - def: '0%', - )!; - offsets.add(parseDecimalOrPercentage(rawOffset)); - } - } - return null; - } - - static Future? radialGradient( - SvgParserState parserState, - bool warningsAsErrors, - ) { - final String? gradientUnits = getAttribute( - parserState.attributes, - 'gradientUnits', - def: null, - ); - bool isObjectBoundingBox = gradientUnits != 'userSpaceOnUse'; - - final String? rawCx = parserState.attribute('cx', def: '50%'); - final String? rawCy = parserState.attribute('cy', def: '50%'); - final String? rawR = parserState.attribute('r', def: '50%'); - final String? rawFx = parserState.attribute('fx', def: rawCx); - final String? rawFy = parserState.attribute('fy', def: rawCy); - final TileMode spreadMethod = parserState.parseTileMode(); - final String id = parserState.buildUrlIri(); - final Matrix4? originalTransform = parseTransform( - parserState.attribute('gradientTransform', def: null), - ); - - final List offsets = []; - final List colors = []; - - if (parserState._currentStartElement!.isSelfClosing) { - final String? href = getHrefAttribute(parserState.attributes); - final DrawableGradient? ref = - parserState._definitions.getGradient('url($href)'); - if (ref == null) { - reportMissingDef(parserState._key, href, 'radialGradient'); - } else { - if (gradientUnits == null) { - isObjectBoundingBox = - ref.unitMode == GradientUnitMode.objectBoundingBox; - } - colors.addAll(ref.colors!); - offsets.addAll(ref.offsets!); - } - } else { - parseStops(parserState, colors, offsets); - } - - late double cx, cy, r, fx, fy; - if (isObjectBoundingBox) { - cx = parseDecimalOrPercentage(rawCx!); - cy = parseDecimalOrPercentage(rawCy!); - r = parseDecimalOrPercentage(rawR!); - fx = parseDecimalOrPercentage(rawFx!); - fy = parseDecimalOrPercentage(rawFy!); - } else { - cx = isPercentage(rawCx!) - ? parsePercentage(rawCx) * parserState.rootBounds.width + - parserState.rootBounds.left - : parserState.parseDoubleWithUnits(rawCx)!; - cy = isPercentage(rawCy!) - ? parsePercentage(rawCy) * parserState.rootBounds.height + - parserState.rootBounds.top - : parserState.parseDoubleWithUnits(rawCy)!; - r = isPercentage(rawR!) - ? parsePercentage(rawR) * - ((parserState.rootBounds.height + parserState.rootBounds.width) / - 2) - : parserState.parseDoubleWithUnits(rawR)!; - fx = isPercentage(rawFx!) - ? parsePercentage(rawFx) * parserState.rootBounds.width + - parserState.rootBounds.left - : parserState.parseDoubleWithUnits(rawFx)!; - fy = isPercentage(rawFy!) - ? parsePercentage(rawFy) * parserState.rootBounds.height + - parserState.rootBounds.top - : parserState.parseDoubleWithUnits(rawFy)!; - } - - parserState._definitions.addGradient( - id, - DrawableRadialGradient( - center: Offset(cx, cy), - radius: r, - focal: (fx != cx || fy != cy) ? Offset(fx, fy) : Offset(cx, cy), - focalRadius: 0.0, - colors: colors, - offsets: offsets, - unitMode: isObjectBoundingBox - ? GradientUnitMode.objectBoundingBox - : GradientUnitMode.userSpaceOnUse, - spreadMethod: spreadMethod, - transform: originalTransform?.storage, - ), - ); - return null; - } - - static Future? linearGradient( - SvgParserState parserState, - bool warningsAsErrors, - ) { - final String? gradientUnits = parserState.attribute('gradientUnits'); - bool isObjectBoundingBox = gradientUnits != 'userSpaceOnUse'; - - final String x1 = parserState.attribute('x1', def: '0%')!; - final String x2 = parserState.attribute('x2', def: '100%')!; - final String y1 = parserState.attribute('y1', def: '0%')!; - final String y2 = parserState.attribute('y2', def: '0%')!; - final String id = parserState.buildUrlIri(); - final Matrix4? originalTransform = parseTransform( - parserState.attribute('gradientTransform'), - ); - final TileMode spreadMethod = parserState.parseTileMode(); - - final List colors = []; - final List offsets = []; - if (parserState._currentStartElement!.isSelfClosing) { - final String? href = getHrefAttribute(parserState.attributes); - final DrawableGradient? ref = - parserState._definitions.getGradient('url($href)'); - if (ref == null) { - reportMissingDef(parserState._key, href, 'linearGradient'); - } else { - if (gradientUnits == null) { - isObjectBoundingBox = - ref.unitMode == GradientUnitMode.objectBoundingBox; - } - colors.addAll(ref.colors!); - offsets.addAll(ref.offsets!); - } - } else { - parseStops(parserState, colors, offsets); - } - - Offset fromOffset, toOffset; - if (isObjectBoundingBox) { - fromOffset = Offset( - parseDecimalOrPercentage(x1), - parseDecimalOrPercentage(y1), - ); - toOffset = Offset( - parseDecimalOrPercentage(x2), - parseDecimalOrPercentage(y2), - ); - } else { - fromOffset = Offset( - isPercentage(x1) - ? parsePercentage(x1) * parserState.rootBounds.width + - parserState.rootBounds.left - : parserState.parseDoubleWithUnits(x1)!, - isPercentage(y1) - ? parsePercentage(y1) * parserState.rootBounds.height + - parserState.rootBounds.top - : parserState.parseDoubleWithUnits(y1)!, - ); - - toOffset = Offset( - isPercentage(x2) - ? parsePercentage(x2) * parserState.rootBounds.width + - parserState.rootBounds.left - : parserState.parseDoubleWithUnits(x2)!, - isPercentage(y2) - ? parsePercentage(y2) * parserState.rootBounds.height + - parserState.rootBounds.top - : parserState.parseDoubleWithUnits(y2)!, - ); - } - - parserState._definitions.addGradient( - id, - DrawableLinearGradient( - from: fromOffset, - to: toOffset, - colors: colors, - offsets: offsets, - spreadMethod: spreadMethod, - unitMode: isObjectBoundingBox - ? GradientUnitMode.objectBoundingBox - : GradientUnitMode.userSpaceOnUse, - transform: originalTransform?.storage, - ), - ); - - return null; - } - - static Future? clipPath( - SvgParserState parserState, bool warningsAsErrors) { - final String id = parserState.buildUrlIri(); - - final List paths = []; - Path? currentPath; - for (XmlEvent event in parserState._readSubtree()) { - if (event is XmlEndElementEvent) { - continue; - } - if (event is XmlStartElementEvent) { - final _PathFunc? pathFn = _svgPathFuncs[event.name]; - - if (pathFn != null) { - final Path nextPath = parserState.applyTransformIfNeeded( - pathFn(parserState), - )!; - nextPath.fillType = parserState.parseFillRule('clip-rule')!; - if (currentPath != null && - nextPath.fillType != currentPath.fillType) { - currentPath = nextPath; - paths.add(currentPath); - } else if (currentPath == null) { - currentPath = nextPath; - paths.add(currentPath); - } else { - currentPath.addPath(nextPath, Offset.zero); - } - } else if (event.name == 'use') { - final String? xlinkHref = getHrefAttribute(parserState.attributes); - final DrawableStyleable? definitionDrawable = - parserState._definitions.getDrawable('url($xlinkHref)'); - - void extractPathsFromDrawable(Drawable? target) { - if (target is DrawableShape) { - paths.add(target.path); - } else if (target is DrawableGroup) { - target.children!.forEach(extractPathsFromDrawable); - } - } - - extractPathsFromDrawable(definitionDrawable); - } else { - final String errorMessage = - 'Unsupported clipPath child ${event.name}'; - if (warningsAsErrors) { - throw UnsupportedError(errorMessage); - } - FlutterError.reportError(FlutterErrorDetails( - exception: UnsupportedError(errorMessage), - informationCollector: () => [ - ErrorDescription( - 'The element contained an unsupported child ${event.name}'), - if (parserState._key != null) ErrorDescription(''), - if (parserState._key != null) - DiagnosticsProperty('Picture key', parserState._key), - ], - library: 'SVG', - context: ErrorDescription('in _Element.clipPath'), - )); - } - } - } - parserState._definitions.addClipPath(id, paths); - return null; - } - - static Future image( - SvgParserState parserState, bool warningsAsErrors) async { - final String? href = getHrefAttribute(parserState.attributes); - if (href == null) { - return; - } - final Offset offset = Offset( - parserState.parseDoubleWithUnits( - parserState.attribute('x', def: '0'), - )!, - parserState.parseDoubleWithUnits( - parserState.attribute('y', def: '0'), - )!, - ); - final Image image = await resolveImage(href); - final Size size = Size( - parserState.parseDoubleWithUnits(parserState.attribute('width')) ?? - image.width.toDouble(), - parserState.parseDoubleWithUnits(parserState.attribute('height')) ?? - image.height.toDouble(), - ); - final DrawableParent parent = parserState._parentDrawables.last.drawable!; - final DrawableStyle? parentStyle = parent.style; - final DrawableRasterImage drawable = DrawableRasterImage( - parserState.attribute('id', def: ''), - image, - offset, - parserState.parseStyle(parserState.rootBounds, parentStyle, - currentColor: parent.color), - size: size, - transform: parseTransform(parserState.attribute('transform'))?.storage, - ); - parserState.checkForIri(drawable); - - parserState.currentGroup!.children!.add(drawable); - } - - static Future text( - SvgParserState parserState, - bool warningsAsErrors, - ) async { - assert(parserState != null); // ignore: unnecessary_null_comparison - assert(parserState.currentGroup != null); - if (parserState._currentStartElement!.isSelfClosing) { - return; - } - - // , -> Collect styles - // TBD - looks like Inkscape supports it, but no browser does. - // XmlNodeType.TEXT/CDATA -> DrawableText - // Track the style(s) and offset(s) for and elements - final Queue<_TextInfo> textInfos = ListQueue<_TextInfo>(); - double lastTextWidth = 0; - - void _processText(String value) { - if (value.isEmpty) { - return; - } - assert(textInfos.isNotEmpty); - final _TextInfo lastTextInfo = textInfos.last; - final Paragraph fill = createParagraph( - value, - lastTextInfo.style, - lastTextInfo.style.fill, - ); - final Paragraph stroke = createParagraph( - value, - lastTextInfo.style, - DrawablePaint.isEmpty(lastTextInfo.style.stroke) - ? transparentStroke - : lastTextInfo.style.stroke, - ); - parserState.currentGroup!.children!.add( - DrawableText( - parserState.attribute('id', def: ''), - fill, - stroke, - lastTextInfo.offset, - lastTextInfo.style.textStyle!.anchor ?? - DrawableTextAnchorPosition.start, - transform: lastTextInfo.transform?.storage, - ), - ); - lastTextWidth = fill.maxIntrinsicWidth; - } - - void _processStartElement(XmlStartElementEvent event) { - _TextInfo? lastTextInfo; - if (textInfos.isNotEmpty) { - lastTextInfo = textInfos.last; - } - final Offset currentOffset = _parseCurrentOffset( - parserState, - lastTextInfo?.offset.translate(lastTextWidth, 0), - ); - Matrix4? transform = parseTransform(parserState.attribute('transform')); - if (lastTextInfo?.transform != null) { - if (transform == null) { - transform = lastTextInfo!.transform; - } else { - transform = lastTextInfo!.transform!.multiplied(transform); - } - } - - final DrawableStyle? parentStyle = - lastTextInfo?.style ?? parserState.currentGroup!.style; - - textInfos.add(_TextInfo( - parserState.parseStyle( - parserState.rootBounds, - parentStyle, - ), - currentOffset, - transform, - )); - if (event.isSelfClosing) { - textInfos.removeLast(); - } - } - - _processStartElement(parserState._currentStartElement!); - - for (XmlEvent event in parserState._readSubtree()) { - if (event is XmlCDATAEvent) { - _processText(event.text.trim()); - } else if (event is XmlTextEvent) { - final String? space = - getAttribute(parserState.attributes, 'space', def: null); - if (space != 'preserve') { - _processText(event.text.trim()); - } else { - _processText(event.text.replaceAll(_trimPattern, '')); - } - } - if (event is XmlStartElementEvent) { - _processStartElement(event); - } else if (event is XmlEndElementEvent) { - textInfos.removeLast(); - } - } - } -} - -// ignore: avoid_classes_with_only_static_members -class _Paths { - static Path circle(SvgParserState parserState) { - final double cx = parserState.parseDoubleWithUnits( - parserState.attribute('cx', def: '0'), - )!; - final double cy = parserState.parseDoubleWithUnits( - parserState.attribute('cy', def: '0'), - )!; - final double r = parserState.parseDoubleWithUnits( - parserState.attribute('r', def: '0'), - )!; - final Rect oval = Rect.fromCircle(center: Offset(cx, cy), radius: r); - return Path()..addOval(oval); - } - - static Path path(SvgParserState parserState) { - final String d = parserState.attribute('d', def: '')!; - return parseSvgPathData(d); - } - - static Path rect(SvgParserState parserState) { - final double x = parserState.parseDoubleWithUnits( - parserState.attribute('x', def: '0'), - )!; - final double y = parserState.parseDoubleWithUnits( - parserState.attribute('y', def: '0'), - )!; - final double w = parserState.parseDoubleWithUnits( - parserState.attribute('width', def: '0'), - )!; - final double h = parserState.parseDoubleWithUnits( - parserState.attribute('height', def: '0'), - )!; - final Rect rect = Rect.fromLTWH(x, y, w, h); - String? rxRaw = parserState.attribute('rx'); - String? ryRaw = parserState.attribute('ry'); - rxRaw ??= ryRaw; - ryRaw ??= rxRaw; - - if (rxRaw != null && rxRaw != '') { - final double rx = parserState.parseDoubleWithUnits(rxRaw)!; - final double ry = parserState.parseDoubleWithUnits(ryRaw)!; - - return Path()..addRRect(RRect.fromRectXY(rect, rx, ry)); - } - - return Path()..addRect(rect); - } - - static Path? polygon(SvgParserState parserState) { - return parsePathFromPoints(parserState, true); - } - - static Path? polyline(SvgParserState parserState) { - return parsePathFromPoints(parserState, false); - } - - static Path? parsePathFromPoints(SvgParserState parserState, bool close) { - final String points = parserState.attribute('points', def: '')!; - if (points == '') { - return null; - } - final String path = 'M$points${close ? 'z' : ''}'; - - return parseSvgPathData(path); - } - - static Path ellipse(SvgParserState parserState) { - final double cx = parserState.parseDoubleWithUnits( - parserState.attribute('cx', def: '0'), - )!; - final double cy = parserState.parseDoubleWithUnits( - parserState.attribute('cy', def: '0'), - )!; - final double rx = parserState.parseDoubleWithUnits( - parserState.attribute('rx', def: '0'), - )!; - final double ry = parserState.parseDoubleWithUnits( - parserState.attribute('ry', def: '0'), - )!; - - final Rect r = Rect.fromLTWH(cx - rx, cy - ry, rx * 2, ry * 2); - return Path()..addOval(r); - } - - static Path line(SvgParserState parserState) { - final double x1 = parserState.parseDoubleWithUnits( - parserState.attribute('x1', def: '0'), - )!; - final double x2 = parserState.parseDoubleWithUnits( - parserState.attribute('x2', def: '0'), - )!; - final double y1 = parserState.parseDoubleWithUnits( - parserState.attribute('y1', def: '0'), - )!; - final double y2 = parserState.parseDoubleWithUnits( - parserState.attribute('y2', def: '0'), - )!; - - return Path() - ..moveTo(x1, y1) - ..lineTo(x2, y2); - } -} - -class _SvgGroupTuple { - _SvgGroupTuple(this.name, this.drawable); - - final String name; - final DrawableParent? drawable; -} - -class _SvgCompatibilityTester extends CacheCompatibilityTester { - bool usesCurrentColor = false; - bool usesFontSize = false; - - @override - bool isCompatible(Object oldData, Object newData) { - if (oldData is! SvgTheme || newData is! SvgTheme) { - return true; - } - if (usesCurrentColor && oldData.currentColor != newData.currentColor) { - return false; - } - if (usesFontSize && oldData.fontSize != newData.fontSize) { - return false; - } - return true; - } -} - -/// The implementation of [SvgParser]. -/// -/// Maintains state while pushing an [XmlPushReader] through the SVG tree. -class SvgParserState { - /// Creates a new [SvgParserState]. - SvgParserState( - Iterable events, - this.theme, - this._key, - this._warningsAsErrors, - ) - // ignore: unnecessary_null_comparison - : assert(events != null), - _eventIterator = events.iterator; - - _SvgCompatibilityTester _compatibilityTester = _SvgCompatibilityTester(); - - /// The theme used when parsing SVG elements. - final SvgTheme theme; - - final Iterator _eventIterator; - final String? _key; - final bool _warningsAsErrors; - final DrawableDefinitionServer _definitions = DrawableDefinitionServer(); - final Queue<_SvgGroupTuple> _parentDrawables = ListQueue<_SvgGroupTuple>(10); - DrawableRoot? _root; - late Map _currentAttributes; - XmlStartElementEvent? _currentStartElement; - - /// The current depth of the reader in the XML hierarchy. - int depth = 0; - - void _discardSubtree() { - final int subtreeStartDepth = depth; - while (_eventIterator.moveNext()) { - final XmlEvent event = _eventIterator.current; - if (event is XmlStartElementEvent && !event.isSelfClosing) { - depth += 1; - } else if (event is XmlEndElementEvent) { - depth -= 1; - assert(depth >= 0); - } - _currentAttributes = {}; - _currentStartElement = null; - if (depth < subtreeStartDepth) { - return; - } - } - } - - Iterable _readSubtree() sync* { - final int subtreeStartDepth = depth; - while (_eventIterator.moveNext()) { - final XmlEvent event = _eventIterator.current; - bool isSelfClosing = false; - if (event is XmlStartElementEvent) { - final Map attributeMap = - event.attributes.toAttributeMap(); - if (getAttribute(attributeMap, 'display') == 'none' || - getAttribute(attributeMap, 'visibility') == 'hidden') { - print('SVG Warning: Discarding:\n\n $event\n\n' - 'and any children it has since it is not visible.\n' - 'If that element is meant to be visible, the `display` or ' - '`visibility` attributes should be removed.\n' - 'If that element is not meant to be visible, it would be better ' - 'to remove it from the SVG file.'); - if (!event.isSelfClosing) { - depth += 1; - _discardSubtree(); - } - continue; - } - _currentAttributes = attributeMap; - _currentStartElement = event; - depth += 1; - isSelfClosing = event.isSelfClosing; - } - yield event; - - if (isSelfClosing || event is XmlEndElementEvent) { - depth -= 1; - assert(depth >= 0); - _currentAttributes = {}; - _currentStartElement = null; - } - if (depth < subtreeStartDepth) { - return; - } - } - } - - /// Drive the [XmlTextReader] to EOF and produce a [DrawableRoot]. - Future parse() async { - _compatibilityTester = _SvgCompatibilityTester(); - for (XmlEvent event in _readSubtree()) { - if (event is XmlStartElementEvent) { - if (startElement(event)) { - continue; - } - final _ParseFunc? parseFunc = _svgElementParsers[event.name]; - await parseFunc?.call(this, _warningsAsErrors); - if (parseFunc == null) { - if (!event.isSelfClosing) { - _discardSubtree(); - } - assert(() { - unhandledElement(event); - return true; - }()); - } - } else if (event is XmlEndElementEvent) { - endElement(event); - } - } - if (_root == null) { - throw StateError('Invalid SVG data'); - } - return _root!; - } - - /// The XML Attributes of the current node in the tree. - Map get attributes => _currentAttributes; - - /// Gets the attribute for the current position of the parser. - String? attribute(String name, {String? def}) => - getAttribute(attributes, name, def: def); - - /// The current group, if any, in the [Drawable] heirarchy. - DrawableParent? get currentGroup { - assert(_parentDrawables != null); // ignore: unnecessary_null_comparison - assert(_parentDrawables.isNotEmpty); - return _parentDrawables.last.drawable; - } - - /// The root bounds of the drawable. - Rect get rootBounds { - assert(_root != null, 'Cannot get rootBounds with null root'); - assert(_root!.viewport != null); // ignore: unnecessary_null_comparison - return _root!.viewport.viewBoxRect; - } - - /// Whether this [DrawableStyleable] belongs in the [DrawableDefinitions] or not. - bool checkForIri(DrawableStyleable? drawable) { - final String iri = buildUrlIri(); - if (iri != emptyUrlIri) { - _definitions.addDrawable(iri, drawable!); - return true; - } - return false; - } - - /// Appends a group to the collection. - void addGroup(XmlStartElementEvent event, DrawableParent? drawable) { - _parentDrawables.addLast(_SvgGroupTuple(event.name, drawable)); - checkForIri(drawable); - } - - /// Appends a [DrawableShape] to the [currentGroup]. - bool addShape(XmlStartElementEvent event) { - final _PathFunc? pathFunc = _svgPathFuncs[event.name]; - if (pathFunc == null) { - return false; - } - - final DrawableParent parent = _parentDrawables.last.drawable!; - final DrawableStyle? parentStyle = parent.style; - final Path path = pathFunc(this)!; - final DrawableStyleable drawable = DrawableShape( - getAttribute(attributes, 'id', def: ''), - path, - parseStyle( - path.getBounds(), - parentStyle, - defaultFillColor: colorBlack, - currentColor: parent.color, - ), - transform: parseTransform(getAttribute(attributes, 'transform'))?.storage, - ); - checkForIri(drawable); - parent.children!.add(drawable); - return true; - } - - /// Potentially handles a starting element. - bool startElement(XmlStartElementEvent event) { - if (event.name == 'defs') { - if (!event.isSelfClosing) { - addGroup( - event, - DrawableGroup( - '__defs__${event.hashCode}', - [], - null, - color: currentGroup?.color, - transform: currentGroup?.transform, - ), - ); - return true; - } - } - return addShape(event); - } - - /// Handles the end of an XML element. - void endElement(XmlEndElementEvent event) { - if (event.name == _parentDrawables.last.name) { - _parentDrawables.removeLast(); - } - } - - /// Prints an error for unhandled elements. - /// - /// Will only print an error once for unhandled/unexpected elements, except for - /// ``, ``, and `` elements. - void unhandledElement(XmlStartElementEvent event) { - final String errorMessage = - 'unhandled element ${event.name}; Picture key: $_key'; - if (_warningsAsErrors) { - // Throw error instead of log warning. - throw UnimplementedError(errorMessage); - } - if (event.name == 'style') { - FlutterError.reportError(FlutterErrorDetails( - exception: UnimplementedError( - 'The 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 MgYEh|7Tk#c1$ZGXHvj+t literal 10223 zcma)ic_5VQ`}g(CVkX2$mKIDxN5mXkS<*w2k<{tPPNOV|B5Ncb(sEigmaH``=hP`% zmP(d}HoHkhqLf`Bp`^rn58vPS_x|_3{xQ$JUiWof_qBYk`>*Y`n-_{M6$OBWY%7Z$ z0AwZr$&oICTGGSf0?|J#c*kaQ$ZcFch(0L6=4?AU`ir7_o&;b5+rrH5Q0DMkH+$FC zVuSbLtu+_4ANj_z#m=~JI^q(x{B?-p%;_N2t;z2o2@)=7^lAs_cGe>Xg)2rEPOK#4m*}|G{yLWk3 z?rQDvtjwDn$ur)XI6k!@=Iu~l$dx<{I-LG21&(~}i>T1AYg;Qhx?2rqzf;9Tj#nIB zD@e*zH9S0dd9CEwRckk3Eh5nqdRAiH`)};lth~BE;Am}o<0*m!Vp2HAy!PN-Zq%jQ z8h^O>7Odc8vlA1OGFKU9&GskXb_XWG|1H_4&8DV*Jn&%XPHVxyiQAl@(Bj)Q?DVpI zBTab`7@tCCvI2X3E39i;q7?UNsJgHX_O(9Q(fFd?SXI@>H|XPPIoP90@QEa!w)&W{ zo!)Kf;d*xu{JJP#@FL<_k4joTxqvOaNHVV zFa6e3kX9GuI3hcn!cQQ zI2B%adHf9(W34CAi~KA8h03&jqhI%|%6N_4KMPgY-98VddNu9F_nIXpy7pCHk^<9B;KA)%R`c+zhJC(P zK;GV8o@8VAya-P{6O?+kqwXPh`C}Q4fo5OsHP@ayxpW}WuT3`MQ|`mg#PTQajri9W zFwZo9_1~O$;`uOPYP6+hW1%vakAM2@cnfB^4Lk(GQ>)P~364qm264HY`z+uo8$1H*!}*@6(wO`TEWVP}i6wg3 zQaBbAMr44ZNyYgo38rDK<_5YlJW?eDE^)L#vKfWLL*1K4A!U>$H&t_n&JUzBCoB!? zEk}CWQ@=n;u>MNrlOP@k=Am&k!6GyPD2!WDCWO9}1w`7wm0;8?Wk%thpfHSfMmIie z?)ifv$usU(H{3gu_N-V8!{N%xUiMwxy7TP2`&vmhExuagZsS{R_sNl1UL?BTP9f`0 zsJG?1iQ(MqNRNlwSCF=!fGX!Cq!EQtm$^sZ6ho9<;^v4%rTP;PvIVY$_O9zxi;xdi z#AmZsMZ6yByYc22*c=0MzuFf=*L$9+WEA^hj?GS5g#o4%&MyjMBzw7!#@1-PeoWjQ zU8tzmp}wLpb>TJ0F9`n@VUmqDuTwNAow^bx1$$J8eC|}?gA)heipp!Z7C;LQ9_r({ z&(5>Ip%Vx$Ajul%d0|Bx!NX&G#rUH`Z$(otjq9}qDE34Qo5OKi_+X#1fK>0an;z&> z_=YM7K=k(MJY1jzZ0ozhX`OvP&w*pC1YK$8xx(ZgR*n6zGemyWtEpIZ7)!ZEuAwOXf~Y#x%ASN^ct?ooTS= z?&^bP+DH+th#LFE?V)XxmuvhY-#{Jt2-8 zHo7Bj{M&vKHBdtE$ODR|5`L{1o;S3%)bN%Yg}<7Tps4Z8(5AqlR01LgZ?-i=4=Y28 zDlw7J&$jgPyqGqM@w5CrQ+D;|ts+gNXgDTEc*_y`qc++C7n0Q` zG{sLP9?De+JLM=4U@IsC3c5_0r0yuC4`kx2vF5X>yGZ{(H)DgT!+l`K@iP)EBUzn@ zmxR@e%n5e}ZX}#XHm7gTf@TcOQIs+#Zc!5SSD$FBE?=(J_OF{5ly(0mH}@zG$8L*qYNZLvkqDp zL)$gdnQIoAf;0w+} zPg2Q932dHwkMy<%4d^oN8)Ke-Oa`TT-VR#=+iO~;3mNZiDGAi1?l~6G!0xW@tPRC6 z4T4Tj1(zNc(sAi^MvMU|`!VCk!l55PY}-3_zR&DZs}@;a5$lmQxhDo|$4s>I7hyds zYYY96G1>GTh>T316zz+DB*pS{@xzw`%TM|7hZ zH|tF(@T-R!HtfMnS#3)a##GwVdRv8!Cy)3lQVw;hkgevt%w+0MAVQ6rHqEpQ^_PXM zz+-I2MO)SjH>Mf%T`qxEH95TRG*>)}jIX_`sZM#P|F4E)@4CY!kwJ1W&=OskaSd(! zb*mcTXh4UZS^wq8_SU3ajuUG8>ffXD@TC^%X22p0nHG=wBY^LB8E^9BR9VJQ>nbE+ z00lE|qY@L}ctPkHBcgut$aIQlA<_YUaiMF^mY-&v^ruItpWLI70>Y6(!`U+;YI}H*OYhefSXcwo}xR;X%Q)6_nzSXieb?fptGTTN-eDLql zy(h!jXDNr*HW^yggbf=3K~3_%C{${3p7FH@ar&KMGcLmBzmK#D{gf2{$JrcmkYgzT zN7eL^hq9$KUVBjS$=zU(U+vP2z7JCCUTJ{*LWet?o~O;&^Se~y;Aon}%C+A?C&uuR zuuJupQPRzAYRRwVxN)Ks4}Ev-*`|{JsUdmoj+k9}N*vDVvdAaE1(mnhr4JGb%&z zIVZCVnLh~W(b=`Ov*&u)65Lqi6{e01Mg8`rU~{S|T0Yr~n$S^a#%(}+hpac6&vJKH zI*Rw9ts3pQo%_&iJDs}DA(7Y*%WP@aYt9#M0a#tIjAH4*z#cbB0#miU_pfmff6F9U zof@G5gFMJ0l}j>veUA1c(KSr9f&5K($t&%LBp@n&;UJ6iYlLv!zd^*OwfeI^VyDW*Y3PxDHBmPPpxk+iC;U|FIOdtS}& z;M_2FPbl__*tApm+}ioJjY|bvcFuL(>Cz@_`xO{((Jp_YH8kFa z<67m`NTdTghmj~|1irM#Ey2Je9X8`_elSdQ)Y%Fta#=R6OBaycc2)kU==U~}b#Q{%xIf~M10^Fui)7tL^LXWP@ zseLd==v{h8g-CuH<(A7~+T$)W;5lfj#oub_#O_SfU_jbO`sThI1;%L_Mkp4fGFCeW z%#VseqfWIPq1H7k0q=a~A3Sa`b$(PK8s+3ed%RX31U`+cw^uqJ7xX{spAAshwG4Rr za#Ko=1_U`@L-3jQ@i5@Sx0c&}8A2^jYyL3VPXSjern5+@swdXD-h?Lm7ahmlX3 zX#wYCrUy?qXBbl#W>(YhT3V61z0{2H8|lvuTfzz(4#l+=24X<&(%Y+c1?T;&|<@5wpSxBYqG3CsyBY6>(_8GLR?xEOjh3rX@t&ZXS^Y zj<|vAqqwj8u93Sk7K6OB&oakrr8Gv4HE?V)_j7Va7UQlDNnly6uZcRs@Tg!C?CCi} z_6xcPS2rzyGZ%CvvKwl#$6qyo^B66qU$O=9QWaR1xDu?;4fY`j@Q|XF`c>dzdxl&Fp)>@{viXbh0DeZB?a7GW2SD76>!YG zQRe5Htl_w;*qsV^Ov!QTntdr#PkLF)N-oac%iRqqlv193A@m(fSR!?y_((}K6>Ji8 z8AaYD(0re~;J+VT>PEmhb!v&@-nyzexn1g{!au&j(XynGy4$dW$@MyBRpOna6lkF>1n?T^G8MYH_75+2pRql|bl96>*+xI0_dFTqrh@ zT{0{u%&fhlKVOvx;$3O=tlm$XSHlVkT@8Lf_+3WF2)|q0739vPb$Ptgbzw!zkvX;@Gwyvv@$8 z?-;tfBthHgUlMQ}GcRy9T^1MGgGB!@M={`U_it>n=5tNoVkIw~DezsTF5N?QEiz79 zsW7T8yQs?gfGG3beG&Msw;}tO%m4w9{Z!J=gQ~QUneqvsqcLqk%H$V`lf6a&_kz9S z{ywsrIAkvY?+qGl@{6`L5LV;!9jd6~^~eGUH1<(*Y^GtJ6|aJ?nXduZSonuTRt9H@ zQW!qdW(KR=m3JWaPmoEixFxe{@XHn8w2}(O{$mx!vKtQx0Jao1i^6x zA-&PZI|mU@i+XjI6>lLbG8$%GXcQDhEmdILKZ_Q?U4*|Hc7kt#Q;7sRWbi+6E^gF> zt_&)?Z_NDny?rhRt(g_E44-i>Mqn9d(K``_wgHk%*8YJ&F^7BrVX!<$ZtrV!C5gN1 zTq+y9ONv-DWXl@u16R(EsUO?5!w7J{%$)a@g^MQ_W8mEFPhA^C6$2PJ10;YD?-b8c zlmfuYE>YPI9MQ>hJ1+PjLK2>Q2}b$vI7<*7b0s<#WJ%%w7Xj=U=TbD7v()=ejx_ML z?s}yKKk8*P0eHIq->Xm)o>J^b$-zQbImti z&z5#@QcwgUJXVl1T1r=8ZvDBbX--S`n*-5;ICj>1>b#lye}21GB6b+**4bFoU~j{& zAp26vK%pAD_MkP>|w&t=woArqnMg`(MV?x5L=geKG*u?`^2}=JjBnK_#Nhv;AEF zBlT&b2SR1=QvtF-7z@Q*5=R9=%I-?tj=t4|Yv1)C1%O8mh)BwSF(Q(o zsQye{Ukn5J2i}wC3uQ(R&THqpg-nBR0X@MjP1NE2R-MTA=6kR`z;P0LvRi=cO?OF)=CO*G83VvceW!C5&z=0vlt2H*#Jcpn;LGcteRPlTQ{zLg#pWzMAsZT+TUgJL=5tmZyT-Z zGW{l=C%j~`{X>*3-&urSuE+n}XAk(DMuPlxKC2vSPhdSdt7JX`$gBP5Q+tOA@T)Sj zIO<)K+ZXl}lHli+@quC(T0H}=?1;(ra) zoJ~3?G*%(>^}nB#fWQpz$rnEA@4HR)$y~jNHV?$=jor@`9V>5;t?t;-;Jrxhu1Zl; z1w86c45FO7PZZ~$+D1!A3s{ZPv3=9|vi4tUpt+;TiR+-yLIT#}ygnaQ4jWlgYu87} zT+1Vy{Ja5s%rpZ231o%6?oktvsg_N{ z*xY`<93&VzVurDcCUO509p2ke);NA&==T!`;@`qq^2hXL-L#&8}8EF~E0~?+YtLmrwqvmp9I}{3Hdb%(s$z z8-lRM?XAdZ8En@^9)Pj{C{SY4$eAAGt$ z{L0QcTEdpjc;Lso{`jC#^%XsULGPI|jQxaBPhVICGWJd5pZ&MS# zdn2D*nMQNI+bom)SYH!36Rr>A^c{=IS5;9Ql2Is;{p2HNv1Jj+uk}%IJer)xQ57oM zwcZ~x*)?uPOy@-4uQTlCzv);*?A=O&?zu4L2I7gIBk%|AM^pVmS|v`(qS!^N(IDSG zT$1UW1pNE!+WAZ0PKnxgEtLhZBS_a9jg#JT_BT`3C0{<DWt}IBUNjjcmC-N;Fhs~DLB?bvI^ed!*(zF z`W2a)iQUmDSW9*TqO1iGW7EhITxdBiNEF78lR>h^X2>(-|0El|+(*0K)>JZCh!JK7 z!(wfVk5Dz#k3YuY)Mvy881|{AABzdF#Ygk+J!Dtlot*t~+3!Gl{2<3RBvnLA;;XqvtQR-tVb>k@-*0>A5_&wa06m>4MM- z+1A?<)y1;|amdC7dJ~m{Uf^3%!{*8%L<%B@JI8g&EM~bllg)Mdw(laq#A};L^6{JZ zuvNV!n*Yb<~+lx z(ksAPttvS@O?+88A(MUYf0-Ws@_(4#;v-N<@Y|GuRH?V|=_MlA8GYDT!+R{VvEwUjD#Zat)c<1GayTxd|a6)ugEYk1{sTZsu~z zz06jC`0-;$S-)TVNVpdA7;yZ3s8+$BrF5RlHF0Lcugt#>UR(^3IW_LWvYHpXUFrpF zE`k|v)N~7ZsPw$&;5f6%?;;iwP=u+l$JA(S_g7kE_@3x6-n5q!XQ_av|H|xd-l+)# z$y*%qIJKySdmU8}*wHuLXpo>X3Hk2r-;TiN3{PP9{WP<#xQz%pv!f<_oW_9} zPp&TW^XhHEN!%Er)>>Yx>FzT_I*m=d@HA$&zUyIbb#Fl@wY*YOSN3IS{itu^XF`Q7 z1fmjEVsa3yE&lqGN_(z5w)Qzz6UFwpwo@F!n?1LEhXX5#dVR?;la$3I{;lZrm=sb+ zwM_P8Qg^1x)U7ZDU@=n`lEhwM5uKaD#Q!GqBD{27kNC8{^i<%za?ep7%0V@8Gk z`g0Wq&bkoXboUHxFf7*{WiO^7U%Qe=F-PDr5`-_`Fto0DD8$WP=|^;!1a3q@9~AI{GW*#x?nvox4s)ZCB6R^AP@r7noDkw4{5}IEkg2mpDXM!d)l{ zs`{md4S)a41DnTQVF;ZrVuO)zV?3h|#hk?vdY~tjKiF5jr1sA!W5wrOgNl~k!;K)_-4x}&c+($?#tbPAE?x+@aT^Z4& zzsQtuUxcqlD>$N}#K0QtIxU_7&WH=;YQ%&^1b4W83`Jjltt39PywNKxJs@ZYsy1cN znd^55i-anOjJk+q&l~e~E~Io5HVBb5tz%nP+(hb07W8<%^DGt0YzN4CNLn=^)S)TE zf7MhtDwhqE$A~HM1p~xHYR(`;afkc(_#iRydito>LnNJv#)?r)JXxX|gdknbAL2L2 zHg7-awfW5#H0@Oh@p!ocQ2QLp-LLJ2ZR{6q!S#>=Xu9~06(E>AB)g`rz5wxe50elV z1~uby1@13%sYGL0b%y`i`NEmO{W$&YsPMpzazVP-^6`fET3YdG*qaDCoZ~Mr%es6+ zmUAv=AtK7R-IdNi>G~_JVhvgo?e2>FepyXex(TWh12Uxt-yIqhm0ycWg4d@rkLpd` zL5IlZ^_2Eqj<72gCqkuh%cm6#qVi5BIdw4_^$+5jR)Mb;g~M>~QO>BMu~bp9vhQDa z!hQU)7K=@)u1@YAQjJ*bPyj!=Lb*r1*KS5d(VJ$FMvQ4@s7GAlYNOIG%Xh2$KQ-ra z`uIr;n8Io)t7Z~;sMMQE>2FaDnS$>pRX?7?i#M}P^W4Pv7Ggj0mns@x36)o~5zcOXZa1#L+n@KsGf!AcKqc8_m}l2q)u|~lYGS)WSBon<)SpHHh-UYog zsrNe9^|vM=m*$lxG}OmHJQ=F0h8ALK_3n~H%Io;Xs&rb!rPKazu1eU{Z!4+(XA~1i zC@}1IpaNy#a@DCaq#S-@t1q_sp|Aoa&QC4igDt9Es7+NMiLDtg(&DGnnH^~>LOB-V zY2@rQRKj%%a8-1_vLSfPqwp{Jn1DO(wOQ3=*g95HFUwmLEV07h+9| zFV;~aO$Z+9*2Nl15=Q79g0MU~o4i?l>T1{;zJ-27+H4O$lZLyI=vk|UW$WMiHWDLc zwn2iSzMEkyfX=krjtXao4XuJ0W)#QEt!%|!<@3nVwQ7kF8YKEFx-z0t5!R~_+q0OY zB8yQJLSymo7#4)g0!1Jz69Qv|M^0&;-!Ybl-YS%<9Rl$LFb|k}sk70H@*Pin7LiD< zBy$d-*B09tSgw9Vrkdm$DT=%nda02bu(R{@5~p)f>pgxVs(73u^}UmLx+5ISu+68@9Iu)HFC=pa%57oR|T za5tk!!S5o8|AWpvbIMRke)+fpNTatV)_oSd$@*}xNrI|@WFau$9Vt73$Yfv2_zbCt zsv4m;i1E=b9QqqYjbHhmdJ$=L%X?#jueW0aRH>Bf7F9?WD(6e&z33^q5(MuM&Ay-O zPYpf!vqErOj(sj&SdgU<(Ti}-ftk1#R1%bTJ>gYmJ!Vp9GRBpGds6uOmG73ghHnxx z9r<`FIW`DVR0#f>c&YnpArR<;00lF7kGOaVa7K@nPQ^=E+6(|^KZUV3mQ_WkD?o@j z#HJ(*i!;W)1^Yj&C~xWUvcA->vuduKD*-QruZrA0FDVgS+5V+WJG9(d_>`(gxoN*D zjVFTMBH1Ck${p5g`|HVxknT;^C<^-PY!6Jt0!aq3BrV)hbHjB7ht^xR%{`AbX>de^ zz_%ffZIc#m#myN=$WN7H+rH>Qp<|b`3>;ZS;O7xFwuw1h}+pcV#j9LBG7@6&+BTuID931}E%A5K4aWQn*045ux zusyeLtHHaHH(y&E<7!WTdU*Ko&Rabuz5D*UOkfa>K&%|}+@sdZfU7c_e0C~1@7~=F zGXY09&++lDZ@Y9Jihi|Ed@=1)p}i+1cv%(3GoDqN82f(jnDoR2gbxCHldVOrIVbM_ E08E}cL;wH) diff --git a/third_party/test/golden_widget/circle.em_ex2.png b/third_party/test/golden_widget/circle.em_ex2.png new file mode 100644 index 0000000000000000000000000000000000000000..9c72bdcbea280fda4aa3b156426e9245db3ad49d GIT binary patch literal 10224 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 MgYEh|7Tk#c1$ZGXHvj+t literal 0 HcmV?d00001 diff --git a/third_party/test/golden_widget/columns_and_rows.png b/third_party/test/golden_widget/columns_and_rows.png index d4baaddf86b636c9e296dce515657b0d4ff1654e..105dbecb54686478846c83fdfa7c9d51bbd730ef 100644 GIT binary patch literal 25790 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 literal 25764 zcmbq*2UJu`v+f`QDgvS;0U45_0wNj7Dl%jQlqeucB!lEMpeUdSLy#<>WR#pUl0lL% z63CU(Q-TkbH6ud|b}yd&6L~FiEldPaHlk4#`?l z8zN`+w4Z*J5`Rq%dq~nvn{umT{4s9x^9+_`?wt1fer0$W`?p(ZQhFn8x9gT=+3B?H zcw^nR?Q0Mcl_`4L8p=y}bEFBIo&qcM7E6jEPc=Vd3&* z7m}NqVwy2XdWxYc{O~Qoy*BNmjXYYI`%@2r41z!{PX)>W?7R}}G+w;^Il|7~VeP^C zwDSI;Y7uQ#Y4Yh06^ASPruR9g-Y6U6JZ-}1GQ`g(I~2RnQ(^6lg+;5^JA206Af20* zs_j7Cf^gHJBxCDEW@XruJeIW155;#iI;GOSOuZX#uh1tZI0x&k6(@(WSbxP*bMEfx zf1#~yx=nAv=cmXjz4DpWXvL95Mu?-?=^#Ju3|fFD)Q9*Cv)NEbWW zN_D;BI==CDt5~QNYQ^pWTTy?C#LoP%@03yQu9Q;&@sYy_G&0TaVjXXPxx?HwO>MA# zWJ^-{$1U&dzEIeo$1onhp}H-!lAYS5F};GY)&6@hk?~kYrbL@-Lw;*WFad#uHGT8I z1naiF5PO~)8w-g%7FU}z4uvZZAQ@N-VS-7#S7Mr5LeE?=AcgesJdJP`56w!2@cq<$UI1z zlt!hWbiGI-yfQfPvzHKw)0h1w>=yqsOg6a#}b z#(^ELe|xRcLRNa`4r8XM-@z2sG-A^;>i!uRqYv0wYQ5rsVvV0|=ybpD8;89%u6mrM zx30lP$tW+uEE|>xHWUt=w@fQ$^b`e1Hxi71(3o3TikyQLzJ(gMgXP?-9(BbZVR^AZ zFr(niG2i>=`skzd~C#Hp{s#xkvl+E*wok;zS{D3_tX1u03IaSwfq` z_q?nR99WT6+h_+{!KgsT=58Kv;Bo88Vb9^v@1tn#NO)0+E&uCxl0|9g;oiOQI*QZZ z7){Hr3i6MzN@|xy|2kvvLnQ+*=7RyHAIcZK%m=TdiWScrXBx=
t*%$@hS!C00^JF1i0X6&Mk*F7tCFiuKoiJG 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�u9vbX{zc#lGCFlb@L2Onwq@UnkgLn5^=% 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 literal 6672 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 literal 0 HcmV?d00001 diff --git a/third_party/test/golden_widget/flutter_logo.asset.png b/third_party/test/golden_widget/flutter_logo.asset.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..c73024a3e8466eac6de9e2e133e3787c6dd8fac6 100644 GIT binary patch literal 10275 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.memory.png b/third_party/test/golden_widget/flutter_logo.memory.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..c73024a3e8466eac6de9e2e133e3787c6dd8fac6 100644 GIT binary patch literal 10275 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.natural.png b/third_party/test/golden_widget/flutter_logo.natural.png index c77f9c29e5ac4f601ed140dee7e27508a6ef7d82..510026df7d61288b94d857d0cf82fa4b06a09fb1 100644 GIT binary patch literal 25928 zcmeI5iC@fH{Qp0=$lkPx78zQ!5LZQM!L&%SPBW-xvR7!Lg^U^sEm!3mt}S&7F_UIo zy0SD)ku2A)ETL|;lrR#LRNwPC@6UYd-v8kD{pE2VSNHun=Y5{%b>8QFme0qPG|$&_ z$iR^U34$0h%Zs&uAO`RWqQ8blKV&JY{P7F=t=Gl{o->GoJBIJkfBdp>#;ipe=$BAq zMIu3%5VKg*7i~K7p|n>o^i-7IA^oU9dh7Ysqd<=WJqq+F(4#<)0zC@!DA1!oj{-dk z^eE7yK#v0drxg%Ay^wMEc0upt9O;UFUWt>BBxblBoBqpC5pi9yF)iGLRhM+j$NP9l z$J@}rv!9AX-37g$IR2kjq^EN|3iK$@qd<=W|34{kwoTB2`^zn#Tk^Bx)whaKofl*J zU#{OZs-wLo?q^FJ=Pr6Ky8rV{19^E)$hK$2wzgNKjdJaHcjd44_6D2JnZv5@mLy5h z!`jitGO|!DKkJpmwNr<8zd5L_^?Y1M(__hMWLKR0g-bpcm?(9F>#WdEn+_3!NXt;B zoH<9>7yWcelTS9J=yjEI3_ImJ^tL98JUOUJo~+bGKYj2PktGQyE#4k8d2fXGVgPQJ zZ(e8h;3@|_5@__&Ba3`+6S^N#k(d2L$0$%qLS&vK_0r~{CKP`F%;#U!FjI~IjPY1C zOdbW(M-5Xu8DNSs)G$XVm}pHk%tL^w^`Kz}0L*h5W;_KGov4O6PQmn3!xT|4fuq$h z1EA?m+tf|3&;Yd!)D5LGp^p>PZrxI$M=lIC+*m+aTW3{=g-SQYRrs4}A7)@c;{#Hr zn}cDo+F<(&_?S)09|R!WR5jUPcRWIh1!~>+QviNH-J6+Oc${Ul`uh7ZtLQyFK=(is zpE>F=+)1Gch7yFuMyg#l>d@2z&b zX&1P?r4B#B0p^cj0Ns!WG~{cphI>98Lgf_Qv=hvqDZACt^qGKB&ZA+B#{!IihS3HX z!!DTr0hlW^j1vW;p@!j`156YR^T7*X3TT*2fO$g02q>6KG|W(tx0aqUifsTh&0Vd` zlmh^>OC3;zIlz3@RKwJc1(=U!YGsa4Fab172EY{2nNZLRlyOkcZ(=+J6F@7o17I%C zQo|HcFdQ1D7c?D6=RFpTzKRZAP0Fp6+O6Af(4)IFoC%;*|CJ<7#0i#|4{on=&f!EZ zvc)A7DDgmM7fk^}8ExnV?ds8?J9q{j5E;E-@J+B&Q8_)V@eCa9)+}}Z^wTjKpP^<| zWP=2Q=ppL|N$$WAb%@zgC|7Be0f1sgqxb-d?P&Fg@tJ^fgGR{!6dxMp0EMDOqZ|Vi zZ5qW4Q1rV{rh+O88l^9w^rKO%DU>c%MgvMIjgkT=gJ~2lg`!ELI2?1PZ?q+u=r z%!e)*O&DS$8phBAOZ|B)4Kou|I%=X8UqFR*JPqRuFq^tyf&nI)9>OUAQ#+J~$pe_@ zUg{}Us|7FyG>kt5Gn9sz4KOdeV5q>hqG7b4=?QcMUWWh^&Qv#K0!!v+dTACJg1q!j zkC+80Xk|WvH+m+su`JeeX&-aIK(E~h3% z0Pq9o-du((>hG%#1Caxs%%a(}CZC6562S=d2omc}@XljAy<=1Ch91AC;fmsMs7%>M zHysTLE|1o&7FOI^9U5jDEcS+7Fy;U=vkM0H?gD)pCJJDNcER`p%tspL$sP>zqzlFg zCiA5(7y?3WI1OV6@=l{?jHnMpOCBw_02cGlbS5Nx0mis%2xbAy3mRq$z!as>%9sO; z1Dy$Ldt;bdGaAMpU@p^fDH;SY4zx0YiFlYkThhw(hNe^KrW0ZGYv^8^fLkHGM-%CT z6MAz+Ob1=6?UlOW__RvEl8JIBGNCnu2*M?}^x92?gW&+(!9KWMMOWzRC*T3mqZbT? z8)lVt4QoGqIuz}o#kPgLmGuldQm11H_`PVA2E)pfK?}(jV3Y%0DB6H>jMn4;pqO=` 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 literal 25892 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 Y!!^}?#TGV3F(lARCwIrZWxSvNA8sgA$p8QV diff --git a/third_party/test/golden_widget/flutter_logo.network.png b/third_party/test/golden_widget/flutter_logo.network.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..c73024a3e8466eac6de9e2e133e3787c6dd8fac6 100644 GIT binary patch literal 10275 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png b/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png index 6b12ded3f96226de0bef22a1502715fdd3b1c757..fd041413932079d90bd1f7402b3d91c4f710e5cd 100644 GIT binary patch literal 9344 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 literal 9168 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 Ef3wSbq5uE@ literal 7618 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 diff --git a/third_party/test/golden_widget/flutter_logo.string.ltr.png b/third_party/test/golden_widget/flutter_logo.string.ltr.png index e4402865634cfd5469cab823e5056404bd347fb8..13f1aa453c9e6c1030dcc2927330ce88ca28175b 100644 GIT binary patch literal 3389 zcmeH|`(Mj@9LGOfIZY3=ZzQK=tJO*&UF6!DS*?pQ^e9BA)I;t`7nLSqlUX&CqN0Nw zq;W(F9W+}~nx%^rl}jmEt-EyI-+ny*0^eV@@ALEeyf3fMh`5gQ2at@2guU=X*uRFuLiv?5+u=oXKg-RV1Wzm}h>y^u&u;AH-cjef-c==? z*D`vp>b6^2eCOS+3IoZdOU?ngHK7^_IZ=GctF?Qwbj_?16n-l5p4|trW!^doU;G=$ zg#nneWvaVac_f~9!{I@2Pp;-g$I}jC&y4U$icZ%JdU5>)N>y*gvZ~&L?~Ydu41bCa zrW2u#-_LIcesKqQVIKX<4%r&@VW{zgu+rl>!?uI=_xtaPj<1-iG_M=Ik2lC=fJu2e z1UNF&TzK&RC`Ltyxitd@c%j46-i3$A+lSAwq^Ut4D^kvdXx9_BSP(UN6-NFWHo3l5 z3&uy@ysRl>6`~m#z6D68{BXJEDBr@C@o22J`_TQhvRP=wR4NK`iA4p51R|6EObb0E zQ_&>PSoF$@KrH0~7{$R#0M-DQ0FD4qgJQk~OxXJdNAb_ z4s@xgQ9OvKJD|W_0v*&tWuiJ3DD**L1d3=-?9`>8HcuWRV=WrI01_Di$D3YY&OjEa zh>&NaA~35pNlZ_O;If>Dl*xl=i#LFmd;o3$_yCl+0)X@|Od+TUrT3v6J%};GoT!=e z1cJ7LpWdfII&&hKrwv(8LbF^O$hwctM3!u5t2LEhpH4fJL6pDnGDwHH==6-p16R6cmy6}kJz1}fpC6GXP%#uq)Uy2X&BNLi`1 zn<710wyOx-DgOTwEmCejx(w`v17P!q5|n z!>dhQ6cgUhX8*9M#lVb85DMB1jA4*Sf0;gLy9+I#sKsCrari{?#THt$gCc5CYMp*G2VBiF zg(;Y$v#dZ>eI^n@^U7hx^lk?x2I)~YMLXjXd)&mgF0OAta$sBnn@ca8lh_85_2ZHW zAXyzEs?2gVnZ92r%HK)@vz0FUm0Bn{+l~{WKQg+qSykQVpLkwm-*l4Sp5+7!7g{!z zj2tG>^FO=}RDz8o%vq>| z!$SqLlSoDC;_U41joah%t9LqQ*e}eEZJaAq=Rg<=e#DLmlKb~$4TXH}IeJ_iY~>Ka z7vj2 zPcMANF>t%VvDlPIPuKWGl2ggvF2&ICRKYb@v7qk9lV}D1u5@K% zXs0k!zOlsc^-_i&W{mpq8=%??yIm4h64#};p6x}y(iGE^VjmdSu|l=`>(qUB`mWt~ zlvuwJ`&9XvXyy!Sl2CEOJl0u#(Y@wJgQ8KlK-+*%ffAd6p>=NuF0adsp8qB@=8q;_ zV^jmD_=|juBkO5V_4m~_H#QFs`UZAf+~d+ynnnv|7^K+S)#Exd(A5{w?)2(=J^uc} zul>k~U-plKrZGC~hV=4n9*M|Xj0ic_w=N70uXQAI&usF?4!@UEK z&d}xDvGgV@jL4k}*W2N6FG{9}FlO^`GgQ3~1PWqoO< xCK6HMckSs2acBJRI|1K|-_LIcet8GfUmnXMJEu?!GMD3CxH)^V^I2OG{sTz&_wxV% literal 3404 zcmeH|`&&|X9LK+hY%;A7Ej3qyNa}igGA~(E5#m7wGqu(-)6|-)P`fBzf@zY~25Lz% zua&deEZ1Y!R&!b|S47%W63Q%1%P2214ND``xzB0O{)+ki&q@lq9 z^G$3_5JK~LT+T*>=1>tLY$1LGq%<{aKU^@u#sD_D*tTR4Zj1zM-X7eyu+mVpJw$1M=DOs z_ZnF}I7;<8>8YsN!a0$BR!#SNO_H_y-wBEeG<)pF7r67}!6S+7-F$gTOLvi=t)c&v z%6Me#wa>Lbi+b|}G$>?t%{uUZcfhGO_Tlq8nhh>koHx6iTRYd(@vS3AZgC&`i zDp`PdA( z+54hSDZ;20eRIT7kntM_Uo=pFuox!*2LXJ9gCYP_0BZpl09b#AuyPjw+X0AhPzb;g zfHQzpx-V+VhAj~|fGi`tbR=7a5gH2>#z<&JMF})e^--2|iZN{CQFWuZ83I$F6Lz)l>{0dN4s0dN5DoCRCN zdK420F|r{>t_4O2-3~z$?OAAfAV`lJ5m|GkB&399&s*!T#x)jHv6ozjUz5yzCjU+<{zYOSrA-b}@EnUK@% zD@opARW+lX_oZEPe9g6Gy6^PJ$vEs13OwtqBlDfLS34YdJ}HKK!=^`D=fpTcXu9H# zrNWps2(^znz4Vvs5j6nE!IUzFB{{P#MFM0O5KhuDGw=(8R+_cucF@mOV!G_}I znp4rT0^SjD)&!glOgK*@gArncIn^Da#op6zsrRCgna3oxlclSjbXe$T5RqWWmYwOd z7dog9tjX`R5C%Z1^K|Hg%VpJZ+BTuW>k*q2Slsc zZT>dOlKRNs0L-g@XdxE=1Rh(Cw-c6AvX zgB5S|1NC8e30t9rRfQ4h$xoJoHRTiF(t1Yf4;j>lpjc}6Flwe(b=w$0*OgI*iHk)V z`f)4Qzs9PVJ!@uej%H5jYNirG$ZwE!G)R=ob+D1udwD+bjB4|VRZ5iH!pHtPmGwdX6Vt4K=k>JY_v$GN_jin8Adu87K(vC&TzzPvX)RVP=?4EY4rdXok1uxWI PNw^z4zhKTqc1+ek!J+%< diff --git a/third_party/test/golden_widget/flutter_logo.string.png b/third_party/test/golden_widget/flutter_logo.string.png index 7b88eeff0280f9170d14a57356ba73fe922ededb..c73024a3e8466eac6de9e2e133e3787c6dd8fac6 100644 GIT binary patch literal 10275 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 OceTRWk)O+RKm31$8ZSuz diff --git a/third_party/test/golden_widget/flutter_logo.string.rtl.png b/third_party/test/golden_widget/flutter_logo.string.rtl.png index 6c8dd292777c2640514e08b937b8d3d764a80b9e..626ffb7fd58574041908d1c5555b7de5dc284f68 100644 GIT binary patch literal 3389 zcmeH|`(M*#6vxkZkW4UOpn{|^Hg0KZSYZjwIR|5SftT(j-o=~>ge@;|3-B9J4hZFD z$mC{IT!AQ3k|Ihv7^FB%kYPZ|O>kTqg3d9d^X+lx0C-dA&))!G!UUjgrq4hki%k3+e~7~y1Ux9aH-7+MOb_#fB04^Cbg>j*)>9#W zl_)xIs6(BaXSP748+qTWs-ok-U5D}?e(?Q7-V$z-SQITSZ`vp+uyNUDx<=CF)Y(49 zidMXBdcXQ-r-)isipV)2tNH7rWU1%1eWP;IGd|g#S?gp+q8zP;N?ohk@*UOB?|Q4B z$95c3zclp4>~p2zI;Nj#2ma>{kcZY-F1=7J=g>&6>jz)-4+{L^`Ev$ij6GV0u0}Be zkB>UYIcSo?ioh!~+mFQm-!PZ}+}$!9Aj1uH7Rzrqh8c2sb(!McyBWFrE!t=y?le>K z?t-0LclbXTOa6D{VPi`z?+Vzn;aS9CDC{Fu3Vk`2@Olw%i=71&* z2&Qe93AvMQ4d1$Qp#LNgA?^qg5X_)J4gw~ERR|0S?6ZL=T8dydf>;WCkH8JVy9gp( zI8dL0Qv?*iEW^S$NdJ(a)m%}UL5wvMBAif>3dCbeRCuGpGuaA8UAZ8o>j_u>2#VO@0}U<>*ns<-!b&UYk7i8I@A>c;hwupsd{3! zsZis;$EiVER^_7mP7m&87ek0_|1DkYKQ`BEOBZKG_YG#W<(U6zLTzJ_vr^@$G~*87 z+DF~{(p=FJYPG^VpA}!SSg+HyQav#DqmX|n%^C*@9Bk;Zal-NvagNRJAMkK-Z`d%w z<)ko4Y6a%#Y(Rv9&OjqbT-4RCSmGxA=4%{B#>(T;D8r+-vh|>tj}{T}zV$)63~#$I z@A<;P)az_?Rg{SiNeftFjlTbPFAUAyJJXspZ}Z??PB~F_okdAxC^>b2?W{$~3QE#T zNv^SZqbMn*B+ZE^QB(-_2RbuSuht1#FEP;UaQVm2OrTz!E3ZhMOeh}F_s1^f-4i%S z{FF!3g}8CQbj_s0=^4jQlqD2mDdZ!(34Hzx-TjtNsn@Moq}a}JN0l#nqF9U-9L`k< zTC4xfNG+Y|_^4AOrGW+5)>cq+k-Tjk( zhR{dhdA3e4j%Qhu?VGgSFr>a0Rrd4B*3c`gb+XfeoZ;{NVuLWu3F?a7=KD{ys$W+e zes$}%uwu?zUP?i*!@4=g-`o~ko zTQ|LOroLe2hWa|#ZtG&FIX{%ot9-Dj^xU>?K1Ml)Sqfs4(|cTr9%@N zN*lfHwT(U|l4NT#9B=Vh&lFo6ql=y}XeGmvcw>pjc++xr%;P(Z_Z`#xWw{Zkdxi&R zY_L6}?Ulv(UB=oAW4}#a2u$$FtTtmESlfHqg$F-j+iA*aUGMYi$e!5G!q~Zw#?MC{ zqXq;xP+9rf*daM5T-Lm@_+>y6h_IW5F!LX%`u5ZuT|1IPClr?0@M`#Un8Z}Ge3PIF z8+uI>f@S!?27Xz8vmNoH&kYRVA)rF(oeay-lB8 Hki>rg9Qpw3 literal 3490 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 DHyc@x literal 4071 zcmeHJ>su4Y9-iGSWVr}Yt5CT`jObG-MpPt1NK_D01+A6GCcLwa-_uJb1Q|dC#}Cg%!9Z)_+`eha-L#Ko+jtJs6uu8x)<@x*m0NSNbJ4$4@%%j%px{e1+l1 zCq~^{QpO|;7bS9jD35>-YMqsbri%KvzpFF4+mw^xyd`XY_tdwteh*cy-d_lk8vSx| zw~g)1#N}ob+wVVmdc{v{J)*x^Lgt6I<`ijNDjlAt_ROWysUPlaYa6&Sp*d}|1Cw!Q zwT%_1Wd@K!`3}`n>sg}`AWvQ<(_W-V-yrCkHHi;~bQ6q&Oba~EvpFDyQD8ERQVw32 z_Aj~A^tJsB_&?%opY+bIafN{@KZT&56?Tq$22K|q7K0s?O@|bBg{~I=FrzGgQs0t0 z!N}rSW9M&ub$)RyGtGh0F4wGM z)@6*w1Ix}m(PL>AL-IXhHvhY+b(#fEpzK{ zDk2yHChF}ABOdG|kXeFC=gg(b!(WiP?@<=ZAsA6_Ndn%UyJcEYm$}psW9Fc~z-kSA zVdn&_n**cAhxO|mxg-eIy|}RgOCL&Exd;|e+59li2B0!gDdqTYZrZ}YG2*f1totKm{HCHYz-Kf>d)Yvxdx+WHZjOEQ z7bJdR!1!`2jZs67Dzrau*c71czD+z8=L z?IzN*?T|F6WBsTFKH3ppZ$RlT1e~0ZI=Guu5u3Zc_P9wCF}i6=^k#_cH#S{yC3)btjBO~r?8rt;h8r`{qv}F)qQ~rxZ3y(5}8r*Rn9Pe z`Kkjw9Z28Z4JYdM_fi=M3h;#C>yF^qHjJQ_Fa&L$+@phlZSnTK)?kwhoA2}dCAj)% z>5=?Re+B@sWAkj40B#nCPX}fehd(aPEDrw{4$a?oCIGN`pvnN~p)k_#C13(jCVHFz zY~3LkfHQNc0O;bL{?Q&UzUc_C$1zDZ{S+#_RCJf%D1zotO8$VF;JK3o&z%F(_~fcn zR{v`-6gIa{PIf@t-}@qmfe)Kt)Z&bnz*SiQS(s6{7i#i>oF*`JrLpcFi2vTmZ_KETp~zaFUrv>47R|sH7YYJ?;s36# zS02h~nCX2o*;%c>;Rru`WQBG#(2OykS?~+@sgjLSuX%)CS4YHu=?k9!yQwZ?K*)lT zksk>$fBnTm+(WX~*g_t;=Ro1+evE4Ub)Z@;0&I6_ASPwJJ?Ic>C*Lre=Gh$-fXJB^s((+6hLo}60A=N8?IZv|E@^WoPL z;%3@z2HDn@_Vx~>xIzMAn>P8P_`ws_?Nom`e^W9etM9;iTylh=qTP8x@@OC|4>zT# zIH~BH?GvzNhyKQu5x-j7oJ@Cn@q<23HW=@6NN*C$Q~8 z?xk*4T#7F()VsuM5*A`#j=9fxv0t(rD7M%~-VcMKd><8&=M^isf0@=-f(y|AKmZDnHD1UBPSh4q>Rn$s3K z;1ny<-j60*mICQq*@MOqh5n){1TmA>y0!JKIU2ZH`QuCMHE~N0%-E){#jBNTh$lLy zSW|jw?s8nhbE)@z5R_9*v$@^km;6Xp7DU|R+45IH0RQ>be*K4Yy~unk@yxn7eu2If I8~LgK1wH#CDgXcg diff --git a/third_party/test/golden_widget/rect.em_ex2.png b/third_party/test/golden_widget/rect.em_ex2.png new file mode 100644 index 0000000000000000000000000000000000000000..03519b9cd0df80b88d6465830d6bf3ffb1be145c GIT binary patch literal 4070 zcmeH~`&$!N8pqE}0t6x$x(j$A5D}p(DIi){?va~h5wLwK1SOCa15&Og2y&Bwrx0%o zHCPd_fu{&s3z(&u@>m)+Q|gfHu?H<7)s2GyqT*NgcKnC1%CL6T<&`j~l4&HXMUDM7|sI8xlOy zNQX}Xu>O0d$L?>AUwS*>%L{(8v3+o5|H+LNNsJn_NRL%XyHC0K`DMM*N|377Ve$Rd z^KZ9wYf&s12asu<;Vu9AsTe6>pkwQQ{^(r)M6&bAFm?9llJ0h2ILzAdS5jckvo8g_ zoLG?Voj&1mKc-^L#wzyJ&vZQ{Y28)eHleeBgKrVfEivjg2-)PCt=3$WbU`Eb0o@!bIZpn8Xp!gb%c8lNC;v@ zwN&w-nsoLI$kd(Nf84N6r1mn?p({j0);;2nG2HK11cX*djw*vdqFX`!;>D5N@ZF9m zano3+f|lNV`iufRsqR%=AIQHI=}a0oLC||SfmMFel{dvy@L0(cS?wSM0i@30;5&3LU5Nc3FU9$GH3(=`TRHq4T^g~0i1vox{AIELqFzj!}q+dP6; zCmJ+%np@bBB>3}t zQYgny5=qh69FV7&5N$m$yy(<=OvC*PuahJYbi@HG}m=4dzLVm!gG0`wh+U zI=FkE!s?R(>d`w9RQ0H(dsqFu%S1XD*DB~86dAT=eH>*wXvlZu57rwuY(>zdU52-x z#W`z$dkf>L>%2!P>*N8soL1`lD}}>fHT&DdIFo^Iu)@qZX-{LUGbwtrBQ4$_Z<_v! zz$x$*)B@HyDuvY(|87wr;{$6nb^cLy0_#7pZU3Ze2v}FCDYkK>iP4+JU@?bHVV#0c zvR4w2sg_uNe+p4<21R4u=?Zkco8$`S;`$mp1tE8{6mle!yR<_9S7T9TnwMrkys(YI z31Yj%IisL#)>Daa4*oMs%_n}|5X%ns5|pp@Z{Uz{6PXt4G{{seHqHWY_V*zf0k@4O zlJ(;kwXkyg95pgrInUUd7b!$g_uZES{m*D(?}!};hbddf^2TtJ+dFRqdS?+r)}&l4 zbA4#qd1KZPL~BQ>(`gKjNM#cR$A4bFQXIyz&I6gr9~RBYm|l=0#}Ywjf;<50hg!mG z3eCDCCIJK}<}4pP-O~;A#MHUYBP5LZeCpaFi@Zjt+dO(VK){tE5^B00O{$ z5(R+Lvul@YI;?#JYn$Q!NP>%#F-io;9b`He-7!2Z@P82WiAn${j}81mshJ<^jQ~~! zjq4M%X6)O^e-bJ)Ira+^P}%Ve;X^!*l+^VgEMHaO(9KmA+BcO2x2H}3x&+b_8r$WW z5<0kW_#u`}B++{h?gcF2AH3}l-6LY#f_8GYASgMZH`aoi}A+z}jJwH&jid`(U^brgo(U2UD9P2EM93xE^`#hT+?roK|7Jb!ghY5_+;$ zPSpNI z(!%=2qbkA#j7eQ*b%?qe#H-0LbzWp=d%o;?|Q-FjbD7mG~-)n z<5BM{Qwtkah%yZJKf)^gFvO)}f|qPz`a49))gaoIW)ubqXXKiQJizr{yEOQQ5zz<= zvDw58)Lodvw0T6b?d8;>GvnOXha7PIF<#;A2X{51bEy=$czIX;trEWfd-QDo)U*9b z=asTD+}(^(>b+uP&TKvcr{ALVRPAc75@2i^qjcZOc8xKy<#^RF8pTySeLdh zdM=m-YcVJZD!kKhRVO}l zQh14LW&RtX4Q>e1>}s{6)2ooH+(E!&g-yC2FW;_t3>n%A>)R8x7Cef93_0<_zvpOd zJ)zAX!}T{FI_%2+AdPU%BFfouQbpRyTz(Jo90t=@`tR&aE#z8BO{Jzarul;sDe3Q= z)Z4zxf79z@S_*>|wt)i?_HlOlf2CiHwYfkAaEGPM8$1g-4u$ZZtqQ{Q^z*28<7E98 DHyc@x literal 0 HcmV?d00001 diff --git a/third_party/test/golden_widget/stick_figure.withclipping.png b/third_party/test/golden_widget/stick_figure.withclipping.png index c9afb8a958f26466cf284c1595c590b5b30ee290..e6039db89e746335a814ce54e205e33d912f7a78 100644 GIT binary patch literal 20024 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 literal 20023 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 diff --git a/third_party/test/loaders_test.dart b/third_party/test/loaders_test.dart new file mode 100644 index 000000000000..39c748a0a097 --- /dev/null +++ b/third_party/test/loaders_test.dart @@ -0,0 +1,31 @@ +import 'dart:typed_data'; + +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + test('Uses the cache', () async { + const TestLoader loader = TestLoader(); + final ByteData bytes = await loader.loadBytes(null); + final ByteData bytes2 = await loader.loadBytes(null); + expect(identical(bytes, bytes2), true); + }); + + test('Empty cache', () async { + svg.cache.maximumSize = 0; + const TestLoader loader = TestLoader(); + final ByteData bytes = await loader.loadBytes(null); + final ByteData bytes2 = await loader.loadBytes(null); + expect(identical(bytes, bytes2), false); + svg.cache.maximumSize = 100; + }); +} + +class TestLoader extends SvgLoader { + const TestLoader({super.theme, super.colorMapper}); + + @override + String provideSvg(void message) { + return ''; + } +} diff --git a/third_party/test/picture_cache_test.dart b/third_party/test/picture_cache_test.dart deleted file mode 100644 index af6c4b48b155..000000000000 --- a/third_party/test/picture_cache_test.dart +++ /dev/null @@ -1,219 +0,0 @@ -import 'package:flutter/widgets.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_svg/src/picture_cache.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:xml/xml.dart'; - -class MockPictureStreamCompleter extends PictureStreamCompleter {} - -void main() { - const String svgString = ''' - - - -'''; - - const String svgString2 = ''' - - - -'''; - - const String svgString3 = ''' - - - -'''; - - late int previousMaximumSize; - setUp(() { - previousMaximumSize = PictureProvider.cache.maximumSize; - }); - - tearDown(() { - PictureProvider.cache.clear(); - PictureProvider.cache.maximumSize = previousMaximumSize; - }); - - testWidgets('Can set a limit on the PictureCache', - (WidgetTester tester) async { - expect(PictureProvider.cache.count, 0); - - PictureProvider.cache.maximumSize = 2; - expect(PictureProvider.cache.count, 0); - - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.string(svgString), - )); - expect(PictureProvider.cache.count, 1); - - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.string(svgString2), - )); - expect(PictureProvider.cache.count, 2); - - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.string(svgString3), - )); - expect(PictureProvider.cache.count, 2); - - PictureProvider.cache.maximumSize = 1; - expect(PictureProvider.cache.count, 1); - }); - - testWidgets('Precache test', (WidgetTester tester) async { - await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: Text('test_text'), - ), - ); - - expect(PictureProvider.cache.count, 0); - - final PictureProvider pictureProvider = StringPicture( - SvgPicture.svgStringDecoderBuilder, - svgString, - )..theme = const SvgTheme( - fontSize: 14.0, - xHeight: 7.0, - ); - - await precachePicture( - pictureProvider, - tester.element(find.text('test_text')), - ); - expect(PictureProvider.cache.count, 1); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.string(svgString), - ), - ); - expect(PictureProvider.cache.count, 1); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.string(svgString2), - ), - ); - expect(PictureProvider.cache.count, 2); - - PictureProvider.cache.clear(); - expect(PictureProvider.cache.count, 0); - }); - - testWidgets('Precache - null context', (WidgetTester tester) async { - const String svgString = ''' - -'''; - - expect(PictureProvider.cache.count, 0); - await precachePicture( - StringPicture( - SvgPicture.svgStringDecoderBuilder, - svgString, - ), - null, - ); - expect(PictureProvider.cache.count, 1); - }); - - testWidgets('Precache with error', (WidgetTester tester) async { - const String svgString = '()); - } - - final PictureProvider pictureProvider = StringPicture( - SvgPicture.svgStringDecoderBuilder, - svgString, - )..theme = const SvgTheme( - currentColor: Color(0xFF05290E), - fontSize: 14.0, - ); - - await precachePicture( - pictureProvider, - tester.element(find.text('test_text')), - onError: errorListener, - ); - - await null; - expect(tester.takeException(), isInstanceOf()); - expect(gotError, isTrue); - }); - - test('Cache Tests with size > 1', () { - final PictureCache cache = PictureCache(); - expect(cache.maximumSize, equals(1000)); - - final MockPictureStreamCompleter completer1 = MockPictureStreamCompleter(); - final MockPictureStreamCompleter completer2 = MockPictureStreamCompleter(); - expect(completer1.cached, false); - expect(completer2.cached, false); - expect(cache.putIfAbsent(1, () => completer1), completer1); - expect(completer1.cached, true); - expect(completer2.cached, false); - - expect(cache.putIfAbsent(1, () => completer1), completer1); - expect(completer1.cached, true); - expect(completer2.cached, false); - - expect(cache.putIfAbsent(2, () => completer2), completer2); - expect(completer1.cached, true); - expect(completer2.cached, true); - - cache.maximumSize = 1; - - expect(completer1.cached, false); - expect(completer2.cached, true); - - cache.clear(); - expect(completer1.cached, false); - expect(completer2.cached, false); - }); - - test('Cache Tests with size = 1', () { - final PictureCache cache = PictureCache(); - expect(cache.maximumSize, equals(1000)); - cache.maximumSize = 1; - expect(cache.maximumSize, equals(1)); - - expect(() => cache.maximumSize = -1, throwsAssertionError); - - final MockPictureStreamCompleter completer1 = MockPictureStreamCompleter(); - final MockPictureStreamCompleter completer2 = MockPictureStreamCompleter(); - expect(completer1.cached, false); - expect(completer2.cached, false); - expect(cache.putIfAbsent(1, () => completer1), completer1); - expect(completer1.cached, true); - expect(completer2.cached, false); - - expect(cache.putIfAbsent(1, () => completer1), completer1); - expect(completer1.cached, true); - expect(completer2.cached, false); - - expect(cache.putIfAbsent(2, () => completer2), completer2); - expect(completer1.cached, false); - expect(completer2.cached, true); - - cache.clear(); - expect(completer1.cached, false); - expect(completer2.cached, false); - }); -} diff --git a/third_party/test/picture_provider_test.dart b/third_party/test/picture_provider_test.dart deleted file mode 100644 index fe9f3255ff0a..000000000000 --- a/third_party/test/picture_provider_test.dart +++ /dev/null @@ -1,199 +0,0 @@ -// ignore_for_file: prefer_const_constructors - -import 'dart:io'; -import 'dart:typed_data'; -import 'dart:ui'; - -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:test/fake.dart'; -import 'package:test/test.dart'; - -// ignore: must_be_immutable -class FakePictureHandle extends Fake implements PictureHandle { - bool disposed = false; - - @override - void dispose() { - disposed = true; - } -} - -class FakePictureInfo extends Fake implements PictureInfo { - @override - late CacheCompatibilityTester compatibilityTester; - - @override - PictureHandle createHandle() { - return FakePictureHandle(); - } -} - -class FakeFile extends Fake implements File {} - -void main() { - group('PictureProvider', () { - SvgTheme? currentTheme; - late CacheCompatibilityTester compatibilityTester; - - PictureInfoDecoder decoderBuilder(SvgTheme theme) { - currentTheme = theme; - return (T bytes, ColorFilter? colorFilter, String key) async => - FakePictureInfo()..compatibilityTester = compatibilityTester; - } - - setUp(() { - compatibilityTester = const CacheCompatibilityTester(); - }); - - group( - 'rebuilds the decoder using decoderBuilder ' - 'when the theme changes', () { - test('NetworkPicture', () async { - const Color color = Color(0xFFB0E3BE); - final NetworkPicture networkPicture = - NetworkPicture(decoderBuilder, 'url') - ..theme = SvgTheme(fontSize: 14.0); - - final PictureInfoDecoder? decoder = networkPicture.decoder; - - const SvgTheme newTheme = SvgTheme( - currentColor: color, - fontSize: 14.0, - xHeight: 6.5, - ); - - networkPicture.theme = newTheme; - - expect(networkPicture.decoder, isNotNull); - expect(networkPicture.decoder, isNot(equals(decoder))); - expect(currentTheme, equals(newTheme)); - }); - - test('FilePicture', () async { - const Color color = Color(0xFFB0E3BE); - final FilePicture filePicture = FilePicture(decoderBuilder, FakeFile()) - ..theme = SvgTheme(fontSize: 14.0); - - final PictureInfoDecoder? decoder = filePicture.decoder; - - const SvgTheme newTheme = SvgTheme( - currentColor: color, - fontSize: 14.0, - xHeight: 6.5, - ); - - filePicture.theme = newTheme; - - expect(filePicture.decoder, isNotNull); - expect(filePicture.decoder, isNot(equals(decoder))); - expect(currentTheme, equals(newTheme)); - }); - - test('MemoryPicture', () async { - const Color color = Color(0xFFB0E3BE); - final MemoryPicture memoryPicture = - MemoryPicture(decoderBuilder, Uint8List(0)) - ..theme = SvgTheme(fontSize: 14.0); - - final PictureInfoDecoder? decoder = memoryPicture.decoder; - - const SvgTheme newTheme = SvgTheme( - currentColor: color, - fontSize: 14.0, - xHeight: 6.5, - ); - - memoryPicture.theme = newTheme; - - expect(memoryPicture.decoder, isNotNull); - expect(memoryPicture.decoder, isNot(equals(decoder))); - expect(currentTheme, equals(newTheme)); - }); - - test('StringPicture', () async { - const Color color = Color(0xFFB0E3BE); - final StringPicture stringPicture = StringPicture(decoderBuilder, '') - ..theme = SvgTheme(fontSize: 14.0); - - final PictureInfoDecoder? decoder = stringPicture.decoder; - - const SvgTheme newTheme = SvgTheme( - currentColor: color, - fontSize: 14.0, - xHeight: 6.5, - ); - - stringPicture.theme = newTheme; - - expect(stringPicture.decoder, isNotNull); - expect(stringPicture.decoder, isNot(equals(decoder))); - expect(currentTheme, equals(newTheme)); - }); - - test('ExactAssetPicture', () async { - const Color color = Color(0xFFB0E3BE); - final ExactAssetPicture exactAssetPicture = - ExactAssetPicture(decoderBuilder, '') - ..theme = SvgTheme(fontSize: 14.0); - - final PictureInfoDecoder? decoder = exactAssetPicture.decoder; - - const SvgTheme newTheme = SvgTheme( - currentColor: color, - fontSize: 14.0, - xHeight: 6.5, - ); - - exactAssetPicture.theme = newTheme; - - expect(exactAssetPicture.decoder, isNotNull); - expect(exactAssetPicture.decoder, isNot(equals(decoder))); - expect(currentTheme, equals(newTheme)); - }); - }); - - test('Evicts from cache when theme changes (incompatible)', () async { - compatibilityTester = _TestCompabitibilityTester(false); - expect(PictureProvider.cache.count, 0); - const Color color = Color(0xFFB0E3BE); - final StringPicture stringPicture = StringPicture(decoderBuilder, ''); - - final PictureStream _ = stringPicture.resolve( - createLocalPictureConfiguration(null), - ); - - await null; - expect(PictureProvider.cache.count, 1); - - stringPicture.theme = SvgTheme(currentColor: color); - - expect(PictureProvider.cache.count, 0); - }); - - test('Does not evict from cache when theme changes (compatible)', () async { - compatibilityTester = _TestCompabitibilityTester(true); - expect(PictureProvider.cache.count, 0); - const Color color = Color(0xFFB0E3BE); - final StringPicture stringPicture = StringPicture(decoderBuilder, ''); - - final PictureStream _ = stringPicture.resolve( - createLocalPictureConfiguration(null), - ); - - await null; - expect(PictureProvider.cache.count, 1); - - stringPicture.theme = SvgTheme(currentColor: color); - - expect(PictureProvider.cache.count, 1); - }); - }); -} - -class _TestCompabitibilityTester extends CacheCompatibilityTester { - _TestCompabitibilityTester(this.compatible); - - final bool compatible; - @override - bool isCompatible(Object oldData, Object newData) => compatible; -} diff --git a/third_party/test/picture_stream_test.dart b/third_party/test/picture_stream_test.dart deleted file mode 100644 index 856c926428fc..000000000000 --- a/third_party/test/picture_stream_test.dart +++ /dev/null @@ -1,134 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/rendering.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:test/test.dart'; - -void main() { - test( - 'Picture does not get disposed if there are outstanding undisposed layers', - () async { - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - canvas.drawPaint(Paint()..color = const Color(0xFFFA0000)); - final Picture picture = recorder.endRecording(); - - final PictureInfo info = PictureInfo( - picture: picture, - viewport: Rect.zero, - size: Size.zero, - compatibilityTester: const CacheCompatibilityTester(), - ); - - final OneFramePictureStreamCompleter completer = - OneFramePictureStreamCompleter(Future.value(info)); - - await null; // wait an event turn for future to resolve. - - expect(info.picture, isNotNull); - final PictureLayer layer = info.createLayer(); - expect(info.picture, isNotNull); - - void listener(PictureInfo? image, bool synchronousCall) {} - - completer.addListener(listener); - completer.removeListener(listener); - expect(info.picture, isNotNull); - - layer.dispose(); - expect(info.picture, null); - }); - - test('Completer disposes layer when removed from cache and no listeners', - () async { - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - canvas.drawPaint(Paint()..color = const Color(0xFFFA0000)); - final Picture picture = recorder.endRecording(); - - final PictureInfo info = PictureInfo( - picture: picture, - viewport: Rect.zero, - size: Size.zero, - compatibilityTester: const CacheCompatibilityTester(), - ); - - final OneFramePictureStreamCompleter completer = - OneFramePictureStreamCompleter(Future.value(info)); - - await null; // wait an event turn for future to resolve. - - expect(info.picture, isNotNull); - expect(completer.cached, false); - - completer.cached = true; - expect(info.picture, isNotNull); - completer.cached = false; - expect(info.picture, null); - }); - - test( - 'Completer disposes layer when removed from cache and no listeners after having a listener', - () async { - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - canvas.drawPaint(Paint()..color = const Color(0xFFFA0000)); - final Picture picture = recorder.endRecording(); - - final PictureInfo info = PictureInfo( - picture: picture, - viewport: Rect.zero, - size: Size.zero, - compatibilityTester: const CacheCompatibilityTester(), - ); - - final OneFramePictureStreamCompleter completer = - OneFramePictureStreamCompleter(Future.value(info)); - - await null; // wait an event turn for future to resolve. - - expect(info.picture, isNotNull); - expect(completer.cached, false); - - void _listener(PictureInfo? image, bool syncCall) {} - completer.addListener(_listener); - completer.cached = true; - - completer.removeListener(_listener); - expect(info.picture, isNotNull); - completer.cached = false; - expect(info.picture, isNull); - }); - - test('Completer disposes layer when last listener drops and not in cache', - () async { - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - canvas.drawPaint(Paint()..color = const Color(0xFFFA0000)); - final Picture picture = recorder.endRecording(); - - final PictureInfo info = PictureInfo( - picture: picture, - viewport: Rect.zero, - size: Size.zero, - compatibilityTester: const CacheCompatibilityTester(), - ); - - final OneFramePictureStreamCompleter completer = - OneFramePictureStreamCompleter(Future.value(info)); - - await null; // wait an event turn for future to resolve. - - expect(info.picture, isNotNull); - expect(completer.cached, false); - - void _listener(PictureInfo? image, bool syncCall) {} - completer.addListener(_listener); - completer.cached = true; - - completer.cached = false; - expect(info.picture, isNotNull); - completer.removeListener(_listener); - expect(info.picture, isNull); - }); -} diff --git a/third_party/test/render_picture_test.dart b/third_party/test/render_picture_test.dart deleted file mode 100644 index 837cd15ee216..000000000000 --- a/third_party/test/render_picture_test.dart +++ /dev/null @@ -1,59 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/rendering.dart'; -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_svg/src/render_picture.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - Picture createPicture(Color color) { - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - canvas.drawPaint(Paint()..color = color); - return recorder.endRecording(); - } - - test('RenderPicture.picture setter avoids unnecessary painting', () { - final Picture picture = createPicture(const Color(0xFFABCDEF)); - final Picture picture2 = createPicture(const Color(0xFF123456)); - - // A and B are render compatible. C is not. - final PictureInfo pictureInfoA = PictureInfo( - picture: picture, - viewport: Rect.zero, - compatibilityTester: const CacheCompatibilityTester(), - ); - - final PictureInfo pictureInfoB = PictureInfo( - picture: picture, - viewport: Rect.zero, - compatibilityTester: const CacheCompatibilityTester(), - ); - - final PictureInfo pictureInfoC = PictureInfo( - picture: picture2, - viewport: Rect.zero, - compatibilityTester: const CacheCompatibilityTester(), - ); - - expect(pictureInfoA == pictureInfoB, false); - expect(pictureInfoA == pictureInfoC, false); - expect(picture == picture2, false); - - final RenderPicture renderPicture = RenderPicture(picture: pictureInfoA); - - expect(renderPicture.debugNeedsPaint, true); - renderPicture.layout(const BoxConstraints()); - PaintingContext(ContainerLayer(), Rect.largest).paintChild( - renderPicture, - Offset.zero, - ); - expect(renderPicture.debugNeedsPaint, false); - - renderPicture.picture = pictureInfoB; - expect(renderPicture.debugNeedsPaint, false); - - renderPicture.picture = pictureInfoC; - expect(renderPicture.debugNeedsPaint, true); - }); -} diff --git a/third_party/test/svg_parsers_test.dart b/third_party/test/svg_parsers_test.dart deleted file mode 100644 index 2c20fd2cb1bd..000000000000 --- a/third_party/test/svg_parsers_test.dart +++ /dev/null @@ -1,1203 +0,0 @@ -import 'dart:ui' show Color, Offset, PathFillType, Size; - -import 'package:flutter_svg/parser.dart'; -import 'package:flutter_svg/src/svg/parsers.dart'; -import 'package:flutter_svg/src/svg/theme.dart'; -import 'package:flutter_svg/src/vector_drawable.dart'; -import 'package:test/test.dart'; -import 'package:vector_math/vector_math_64.dart'; - -import 'xml_svg_test.dart'; - -void main() { - test('SVG Multiple transform parser tests', () { - Matrix4 expected = Matrix4.identity(); - expected.translate(0.338957, 0.010104, 0); - expected.translate(-0.5214, 0.125, 0); - expected.translate(0.987, 0.789, 0); - expect( - parseTransform( - 'translate(0.338957,0.010104), translate(-0.5214,0.125),translate(0.987,0.789)'), - expected); - - expected = Matrix4.translationValues(0.338957, 0.010104, 0); - expected.scale(0.869768, 1.000000, 1.0); - expect( - parseTransform('translate(0.338957,0.010104),scale(0.869768,1.000000)'), - expected); - }); - - test('SVG Transform parser tests', () { - expect(() => parseTransform('invalid'), throwsStateError); - expect(() => parseTransform('transformunsupported(0,0)'), throwsStateError); - - expect(parseTransform('skewX(60)'), Matrix4.skewX(60.0)); - expect(parseTransform('skewY(60)'), Matrix4.skewY(60.0)); - expect(parseTransform('translate(10,0.0)'), - Matrix4.translationValues(10.0, 0.0, 0.0)); - expect(parseTransform('skewX(60)'), Matrix4.skewX(60.0)); - - expect(parseTransform('scale(10)'), - Matrix4.identity()..scale(10.0, 10.0, 1.0)); - expect(parseTransform('scale(10, 15)'), - Matrix4.identity()..scale(10.0, 15.0, 1.0)); - - expect(parseTransform('rotate(20)'), Matrix4.rotationZ(radians(20.0))); - expect( - parseTransform('rotate(20, 30)'), - Matrix4.identity() - ..translate(30.0, 30.0) - ..rotateZ(radians(20.0)) - ..translate(-30.0, -30.0)); - expect( - parseTransform('rotate(20, 30, 40)'), - Matrix4.identity() - ..translate(30.0, 40.0) - ..rotateZ(radians(20.0)) - ..translate(-30.0, -40.0)); - - expect( - parseTransform('matrix(1.5, 2.0, 3.0, 4.0, 5.0, 6.0)'), - Matrix4.fromList([ - 1.5, 2.0, 0.0, 0.0, // - 3.0, 4.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 5.0, 6.0, 0.0, 1.0 - ])); - - expect( - parseTransform('matrix(1.5, 2.0, 3.0, 4.0, 5.0, 6.0 )'), - Matrix4.fromList([ - 1.5, 2.0, 0.0, 0.0, // - 3.0, 4.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 5.0, 6.0, 0.0, 1.0 - ])); - - expect(parseTransform('rotate(20)\n\tscale(10)'), - Matrix4.rotationZ(radians(20.0))..scale(10.0, 10.0, 1.0)); - }); - - test('FillRule tests', () { - expect(parseRawFillRule(''), PathFillType.nonZero); - expect(parseRawFillRule(null), isNull); - expect(parseRawFillRule('inherit'), isNull); - expect(parseRawFillRule('nonzero'), PathFillType.nonZero); - expect(parseRawFillRule('evenodd'), PathFillType.evenOdd); - expect(parseRawFillRule('invalid'), PathFillType.nonZero); - }); - - test('TextAnchor tests', () { - expect(parseTextAnchor(''), DrawableTextAnchorPosition.start); - expect(parseTextAnchor(null), DrawableTextAnchorPosition.start); - expect(parseTextAnchor('inherit'), isNull); - expect(parseTextAnchor('start'), DrawableTextAnchorPosition.start); - expect(parseTextAnchor('middle'), DrawableTextAnchorPosition.middle); - expect(parseTextAnchor('end'), DrawableTextAnchorPosition.end); - }); - - T? find(Drawable drawable, String id) { - if (drawable.id == id && drawable is T) { - return drawable; - } - - if (drawable is DrawableParent) { - final DrawableParent parent = drawable; - for (Drawable item in parent.children!) { - final Drawable? found = find(item, id); - - if (found != null) { - return found as T; - } - } - } - return null; - } - - test('Font size parsing tests', () { - const double fontSize = 14.0; - const double xHeight = 7.0; - - final TestSvgParserState parserState = TestSvgParserState( - fontSize: fontSize, - xHeight: xHeight, - ); - expect( - parserState.parseFontSize(null), - isNull, - ); - expect( - parserState.parseFontSize(''), - isNull, - ); - expect( - parserState.parseFontSize('1'), - equals(1), - ); - expect( - parserState.parseFontSize(' 1 '), - equals(1), - ); - expect( - parserState.parseFontSize('xx-small'), - equals(10), - ); - expect( - parserState.parseFontSize('x-small'), - equals(12), - ); - expect( - parserState.parseFontSize('small'), - equals(14), - ); - expect( - parserState.parseFontSize('medium'), - equals(18), - ); - expect( - parserState.parseFontSize('large'), - equals(22), - ); - expect( - parserState.parseFontSize('x-large'), - equals(26), - ); - expect( - parserState.parseFontSize('xx-large'), - equals(32), - ); - - expect( - parserState.parseFontSize('larger'), - equals(parserState.parseFontSize('large')), - ); - expect( - parserState.parseFontSize( - 'larger', - parentValue: parserState.parseFontSize('large'), - ), - equals( - parserState.parseFontSize('large')! * 1.2, - ), - ); - expect( - parserState.parseFontSize('smaller'), - equals( - parserState.parseFontSize('small'), - ), - ); - expect( - parserState.parseFontSize( - 'smaller', - parentValue: parserState.parseFontSize('large'), - ), - equals( - parserState.parseFontSize('large')! / 1.2, - ), - ); - - expect(() => parserState.parseFontSize('invalid'), - throwsA(const TypeMatcher())); - }); - - test('relative font size tests', () { - const double fontSize = 26.0; - const double xHeight = 14.0; - - final TestSvgParserState parserState = TestSvgParserState( - fontSize: fontSize, - xHeight: xHeight, - ); - - expect( - parserState.parseFontSize('4em'), - equals(4 * fontSize), - ); - - expect( - parserState.parseFontSize(' 2em '), - equals(2 * fontSize), - ); - - expect( - parserState.parseFontSize('4rem'), - equals(4 * fontSize), - ); - - expect( - parserState.parseFontSize(' 2rem '), - equals(2 * fontSize), - ); - - expect( - parserState.parseFontSize('4ex'), - equals(4 * xHeight), - ); - - expect( - parserState.parseFontSize(' 2ex '), - equals(2 * xHeight), - ); - }); - - test('Check no child with id for svg', () async { - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - '', - ); - expect(root.children.isEmpty, true); - expect(root.id == 'test', true); - }); - - test('Check any ids', () async { - const String svgStr = - ''' - - - - - - - - - - - - - - - - - - -'''; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse(svgStr); - - expect(root.id == 'svgRoot', true); - expect(find(root, 'group1') != null, true); - expect(find(root, 'path1') != null, true); - expect(find(root, 'path2') != null, true); - expect(find(root, 'path3') != null, true); - expect(find(root, 'path4') != null, true); - }); - - test('Check No Svg id', () async { - const String svgStr = ''' - - - svg/stick_figure - Created with Sketch. - - - - - - - - - - - - -'''; - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse(svgStr); - - expect(root.id!.isEmpty, true); - expect(find(root, 'Page-1') != null, true); - expect(find(root, 'iPhone-8') != null, true); - expect(find(root, 'stick_figure') != null, true); - expect(find(root, 'Oval') != null, true); - }); - - test('Throws with unsupported elements with warnings as errors enabled', - () async { - const String svgStr = ''' - - - svg/stick_figure - Created with Sketch. - - - - - - - - - - - - - -'''; - final SvgParser parser = SvgParser(); - expect( - parser.parse(svgStr, warningsAsErrors: true), - throwsA(anything), - ); - }); - - test('Warns about unsupported elements by default', () async { - const String svgStr = ''' - - - svg/stick_figure - Created with Sketch. - - - - - - - - - - - - - -'''; - - final SvgParser parser = SvgParser(); - expect(await parser.parse(svgStr), isA()); - }); - - test('Respects whitespace attribute', () async { - const String svgStr = ''' - - - -'''; - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse(svgStr); - - expect(find(root, 'preserve-space') != null, true); - // Empty text elements get removed - expect(find(root, 'remove-space') != null, false); - }); - - group('currentColor', () { - group('stroke', () { - test( - 'respects currentColor from SvgTheme ' - 'when no color attribute exists on the parent', () async { - const String svgStr = ''' - - -'''; - - const Color currentColor = Color(0xFFB0E3BE); - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - currentColor: currentColor, - fontSize: 14.0, - ), - ); - - final DrawableShape? circle = find(root, 'circle'); - - expect(circle, isNotNull); - - expect( - circle!.style.stroke?.color, - equals(currentColor), - ); - }); - - test( - 'respects currentColor from SvgTheme ' - 'when the parent uses currentColor', () async { - const String svgStr = ''' - - - - -'''; - - const Color currentColor = Color(0xFFB0E3BE); - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - currentColor: currentColor, - fontSize: 14.0, - ), - ); - - final DrawableShape? circle = find(root, 'circle'); - - expect(circle, isNotNull); - - expect( - circle!.style.stroke?.color, - equals(currentColor), - ); - }); - - test( - 'respects currentColor from the parent ' - 'when the parent overrides currentColor', () async { - const String svgStr = ''' - - - - -'''; - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - currentColor: Color(0xFFB0E3BE), - fontSize: 14.0, - ), - ); - - final DrawableShape? circle = find(root, 'circle'); - - expect(circle, isNotNull); - - expect( - circle!.style.stroke?.color, - equals(const Color(0xffC460B7)), - ); - }); - }); - - group('fill', () { - test( - 'respects currentColor from SvgTheme ' - 'when no color attribute exists on the parent', () async { - const String svgStr = ''' - - -'''; - - const Color currentColor = Color(0xFFB0E3BE); - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - currentColor: currentColor, - fontSize: 14.0, - ), - ); - - final DrawableShape? circle = find(root, 'circle'); - - expect(circle, isNotNull); - - expect( - circle!.style.fill?.color, - equals(currentColor), - ); - }); - - test( - 'respects currentColor from SvgTheme ' - 'when the parent uses currentColor', () async { - const String svgStr = ''' - - - - -'''; - - const Color currentColor = Color(0xFFB0E3BE); - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - currentColor: currentColor, - fontSize: 14.0, - ), - ); - - final DrawableShape? circle = find(root, 'circle'); - - expect(circle, isNotNull); - - expect( - circle!.style.fill?.color, - equals(currentColor), - ); - }); - - test( - 'respects currentColor from the parent ' - 'when the parent overrides currentColor', () async { - const String svgStr = ''' - - - - -'''; - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - currentColor: Color(0xFFB0E3BE), - fontSize: 14.0, - ), - ); - - final DrawableShape? circle = find(root, 'circle'); - - expect(circle, isNotNull); - - expect( - circle!.style.fill?.color, - equals(const Color(0xFFC460B7)), - ); - }); - }); - - group('stop-color', () { - test( - 'respects currentColor from SvgTheme ' - 'when no color attribute exists on the parent', () async { - const String svgStr = ''' - - - - - - - - -'''; - - const Color currentColor = Color(0xFFB0E3BE); - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - currentColor: currentColor, - fontSize: 14.0, - ), - ); - - final DrawableLinearGradient? gradient = - root.definitions.getGradient('url(#gradient-1)'); - - expect(gradient, isNotNull); - - expect( - gradient!.colors?[0], - equals(currentColor.withOpacity(0.5)), - ); - - expect( - gradient.colors?[1], - equals(currentColor.withOpacity(0.8)), - ); - }); - - test( - 'respects currentColor from SvgTheme ' - 'when the parent uses currentColor', () async { - const String svgStr = ''' - - - - - - - - -'''; - - const Color currentColor = Color(0xFFB0E3BE); - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - currentColor: currentColor, - fontSize: 14.0, - ), - ); - - final DrawableLinearGradient? gradient = - root.definitions.getGradient('url(#gradient-1)'); - - expect(gradient, isNotNull); - - expect( - gradient!.colors?[0], - equals(currentColor.withOpacity(0.5)), - ); - - expect( - gradient.colors?[1], - equals(currentColor.withOpacity(0.8)), - ); - }); - - test( - 'respects currentColor from the parent ' - 'when the parent overrides currentColor', () async { - const String svgStr = ''' - - - - - - - - - - -'''; - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - currentColor: Color(0xFFB0E3BE), - fontSize: 14.0, - ), - ); - - final DrawableLinearGradient? gradient = - root.definitions.getGradient('url(#gradient-1)'); - - expect(gradient, isNotNull); - - expect( - gradient!.colors?[0], - equals(const Color(0xFFC460B7).withOpacity(0.5)), - ); - - expect( - gradient.colors?[1], - equals(const Color(0xFFC460B7).withOpacity(0.8)), - ); - }); - }); - }); - - group('calculates em units based on the font size for', () { - test('svg (width, height)', () async { - const String svgStr = ''' - -'''; - - const double fontSize = 26.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - ), - ); - - expect(root.viewport.width, equals(fontSize * 5)); - expect(root.viewport.height, equals(fontSize * 6)); - }); - - test('use (x, y)', () async { - const String svgStr = ''' - - - - -'''; - - const double fontSize = 26.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - ), - ); - - final DrawableGroup? circle = find(root, 'anotherCircle'); - - const double expectedX = fontSize * 2; - const double expectedY = fontSize * 4; - - expect(circle, isNotNull); - expect( - circle!.transform, - equals( - (Matrix4.identity()..translate(expectedX, expectedY)).storage, - ), - ); - }); - - test('text (x, y)', () async { - const String svgStr = ''' - - Test - -'''; - - const double fontSize = 26.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - ), - ); - - final DrawableText? text = find(root, 'text'); - - const Offset expectedOffset = Offset(fontSize * 2, fontSize * 4); - - expect(text, isNotNull); - expect(text!.offset, equals(expectedOffset)); - }); - - test('radialGradient (cx, cy, r, fx, fy)', () async { - const String svgStr = ''' - - - - - - - - -'''; - - const double fontSize = 26.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - ), - ); - - final DrawableRadialGradient? gradient = - root.definitions.getGradient('url(#gradient)'); - - expect(gradient, isNotNull); - - const Offset expectedOffset = Offset(fontSize * 1, fontSize * 2); - const double expectedRadius = fontSize * 1.1; - const Offset expectedFocal = Offset(fontSize * 1.5, fontSize * 1.6); - - expect(gradient, isNotNull); - expect(gradient!.center, equals(expectedOffset)); - expect(gradient.radius, equals(expectedRadius)); - expect(gradient.focal, equals(expectedFocal)); - }); - - test('linearGradient (x1, y1, x2, y2)', () async { - const String svgStr = ''' - - - - - - - -'''; - - const double fontSize = 26.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - ), - ); - - final DrawableLinearGradient? gradient = - root.definitions.getGradient('url(#gradient)'); - - expect(gradient, isNotNull); - - const Offset expectedFromOffset = Offset(fontSize * 1, fontSize * 1.75); - const Offset expectedToOffset = Offset(fontSize * 1.5, fontSize * 1.6); - - expect(gradient, isNotNull); - expect(gradient!.from, equals(expectedFromOffset)); - expect(gradient.to, equals(expectedToOffset)); - }); - - test('image (x, y, width, height)', () async { - const String svgStr = ''' - - - -'''; - - const double fontSize = 26.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - ), - ); - - final DrawableRasterImage? image = - find(root, 'image'); - - const Offset expectedOffset = Offset(fontSize * 1, fontSize * 0.5); - const Size expectedSize = Size(fontSize * 2, fontSize * 1.5); - - expect(image, isNotNull); - expect(image!.offset, equals(expectedOffset)); - expect(image.size, equals(expectedSize)); - }); - }); - - group('calculates ex units based on the x-height for', () { - test('svg (width, height)', () async { - const String svgStr = ''' - -'''; - - const double fontSize = 26.0; - const double xHeight = 11.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - xHeight: xHeight, - ), - ); - - expect(root.viewport.width, equals(xHeight * 5)); - expect(root.viewport.height, equals(xHeight * 6)); - }); - - test('use (x, y)', () async { - const String svgStr = ''' - - - - -'''; - - const double fontSize = 26.0; - const double xHeight = 11.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - xHeight: xHeight, - ), - ); - - final DrawableGroup? circle = find(root, 'anotherCircle'); - - const double expectedX = xHeight * 2; - const double expectedY = xHeight * 4; - - expect(circle, isNotNull); - expect( - circle!.transform, - equals( - (Matrix4.identity()..translate(expectedX, expectedY)).storage, - ), - ); - }); - - test('text (x, y)', () async { - const String svgStr = ''' - - Test - -'''; - - const double fontSize = 26.0; - const double xHeight = 11.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - xHeight: xHeight, - ), - ); - - final DrawableText? text = find(root, 'text'); - - const Offset expectedOffset = Offset(xHeight * 2, xHeight * 4); - - expect(text, isNotNull); - expect(text!.offset, equals(expectedOffset)); - }); - - test('radialGradient (cx, cy, r, fx, fy)', () async { - const String svgStr = ''' - - - - - - - - -'''; - - const double fontSize = 26.0; - const double xHeight = 11.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - xHeight: xHeight, - ), - ); - - final DrawableRadialGradient? gradient = - root.definitions.getGradient('url(#gradient)'); - - expect(gradient, isNotNull); - - const Offset expectedOffset = Offset(xHeight * 1, xHeight * 2); - const double expectedRadius = xHeight * 1.1; - const Offset expectedFocal = Offset(xHeight * 1.5, xHeight * 1.6); - - expect(gradient, isNotNull); - expect(gradient!.center, equals(expectedOffset)); - expect(gradient.radius, equals(expectedRadius)); - expect(gradient.focal, equals(expectedFocal)); - }); - - test('linearGradient (x1, y1, x2, y2)', () async { - const String svgStr = ''' - - - - - - - -'''; - - const double fontSize = 26.0; - const double xHeight = 11.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - xHeight: xHeight, - ), - ); - - final DrawableLinearGradient? gradient = - root.definitions.getGradient('url(#gradient)'); - - expect(gradient, isNotNull); - - const Offset expectedFromOffset = Offset(xHeight * 1, xHeight * 1.75); - const Offset expectedToOffset = Offset(xHeight * 1.5, xHeight * 1.6); - - expect(gradient, isNotNull); - expect(gradient!.from, equals(expectedFromOffset)); - expect(gradient.to, equals(expectedToOffset)); - }); - - test('image (x, y, width, height)', () async { - const String svgStr = ''' - - - -'''; - - const double fontSize = 26.0; - const double xHeight = 11.0; - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: const SvgTheme( - fontSize: fontSize, - xHeight: xHeight, - ), - ); - - final DrawableRasterImage? image = - find(root, 'image'); - - const Offset expectedOffset = Offset(xHeight * 1, xHeight * 0.5); - const Size expectedSize = Size(xHeight * 2, xHeight * 1.5); - - expect(image, isNotNull); - expect(image!.offset, equals(expectedOffset)); - expect(image.size, equals(expectedSize)); - }); - }); - - test('Tracks current color', () async { - const String svgStr = ''' - - -'''; - - const Color currentColor = Color(0xFFB0E3BE); - - const SvgTheme oldTheme = SvgTheme( - currentColor: currentColor, - fontSize: 14.0, - ); - - final SvgTheme newTheme = SvgTheme( - currentColor: currentColor.withAlpha(50), - fontSize: 14.0, - ); - - const SvgTheme newTheme2 = SvgTheme( - currentColor: currentColor, - fontSize: 15.0, - ); - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: oldTheme, - ); - - expect(root.compatibilityTester.isCompatible(oldTheme, newTheme), false); - expect(root.compatibilityTester.isCompatible(oldTheme, newTheme2), true); - }); - - test('Tracks em/ex', () async { - const String svgStr = ''' - - -'''; - - const Color currentColor = Color(0xFFB0E3BE); - - const SvgTheme oldTheme = SvgTheme( - currentColor: currentColor, - fontSize: 14.0, - ); - - final SvgTheme newTheme = SvgTheme( - currentColor: currentColor.withAlpha(50), - fontSize: 14.0, - ); - - const SvgTheme newTheme2 = SvgTheme( - currentColor: currentColor, - fontSize: 15.0, - ); - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse( - svgStr, - theme: oldTheme, - ); - - expect(root.compatibilityTester.isCompatible(oldTheme, newTheme), true); - expect(root.compatibilityTester.isCompatible(oldTheme, newTheme2), false); - }); - - test('Preserves stroke-width when gradient is used', () async { - const String svgStr = ''' - - - - - - - - -'''; - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse(svgStr); - - expect(root.children.length, 1); - final DrawableShape circle = root.children.first as DrawableShape; - expect(circle.style.stroke!.strokeWidth, 10); - expect(circle.style.stroke!.strokeMiterLimit, 4); - }); - - test('Preserves stroke properties from group with no "stroke"', () async { - const String svgStr = ''' - - - - - - - - - - -'''; - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse(svgStr); - - expect(root.children.length, 1); - expect(root.children.length, 1); - final DrawableGroup group = root.children.first as DrawableGroup; - final DrawableShape circle = group.children!.first as DrawableShape; - expect(circle.style.stroke!.strokeWidth, 10); - expect(circle.style.stroke!.strokeMiterLimit, 8); - }); - - test('Takes stroke properties from shape when group has them', () async { - const String svgStr = ''' - - - - - - - - - - -'''; - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse(svgStr); - - expect(root.children.length, 1); - expect(root.children.length, 1); - final DrawableGroup group = root.children.first as DrawableGroup; - final DrawableShape circle = group.children!.first as DrawableShape; - expect(circle.style.stroke!.strokeWidth, 5); - expect(circle.style.stroke!.strokeMiterLimit, 8); - }); - - test('Defaults image height/width when not specified', () async { - // 1x1 PNG image from png-pixel.com. - const String svgStr = ''' - - -'''; - - final SvgParser parser = SvgParser(); - final DrawableRoot root = await parser.parse(svgStr); - - expect(root.children.length, 1); - final DrawableRasterImage image = - root.children.first as DrawableRasterImage; - expect(image.size!.width, image.image.width); - expect(image.size!.height, image.image.height); - }); -} diff --git a/third_party/test/theme_test.dart b/third_party/test/theme_test.dart deleted file mode 100644 index 71b88879ee35..000000000000 --- a/third_party/test/theme_test.dart +++ /dev/null @@ -1,88 +0,0 @@ -// ignore_for_file: prefer_const_constructors - -import 'package:flutter/material.dart'; -import 'package:flutter_svg/src/svg/theme.dart'; -import 'package:test/test.dart'; - -void main() { - group('SvgTheme', () { - group('constructor', () { - test('sets currentColor', () { - const Color currentColor = Color(0xFFB0E3BE); - - expect( - SvgTheme( - currentColor: currentColor, - fontSize: 14.0, - ).currentColor, - equals(currentColor), - ); - }); - - test('sets fontSize', () { - const double fontSize = 14.0; - - expect( - SvgTheme( - currentColor: Color(0xFFB0E3BE), - fontSize: fontSize, - ).fontSize, - equals(fontSize), - ); - }); - - test( - 'sets fontSize to 14 ' - 'by default', () { - expect( - SvgTheme(), - equals( - SvgTheme(fontSize: 14.0), - ), - ); - }); - - test('sets xHeight', () { - const double xHeight = 8.0; - - expect( - SvgTheme( - fontSize: 26.0, - xHeight: xHeight, - ).xHeight, - equals(xHeight), - ); - }); - - test( - 'sets xHeight as fontSize divided by 2 ' - 'by default', () { - const double fontSize = 16.0; - - expect( - SvgTheme( - fontSize: fontSize, - ).xHeight, - equals(fontSize / 2), - ); - }); - }); - - test('supports value equality', () { - expect( - SvgTheme( - currentColor: Color(0xFF6F2173), - fontSize: 14.0, - xHeight: 6.0, - ), - equals( - SvgTheme( - currentColor: Color(0xFF6F2173), - fontSize: 14.0, - xHeight: 6.0, - ), - ), - ); - }); - }); -} diff --git a/third_party/test/vector_drawable_test.dart b/third_party/test/vector_drawable_test.dart deleted file mode 100644 index 72a6adf2aec8..000000000000 --- a/third_party/test/vector_drawable_test.dart +++ /dev/null @@ -1,150 +0,0 @@ -import 'dart:typed_data'; -import 'dart:ui'; - -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_test/flutter_test.dart'; - -void main() { - test('DrawableRoot can mergeStyle', () { - const DrawableStyle styleA = DrawableStyle( - groupOpacity: 0.5, - pathFillType: PathFillType.evenOdd, - ); - const DrawableStyle styleB = DrawableStyle( - pathFillType: PathFillType.nonZero, - ); - DrawableRoot root = DrawableRoot( - '', // No id - const DrawableViewport(Size(100, 100), Size(100, 100)), - [], - DrawableDefinitionServer(), - styleA, - ); - expect(root.style!.pathFillType, styleA.pathFillType); - root = root.mergeStyle(styleB); - expect(root.style!.pathFillType, styleB.pathFillType); - }); - - test('SvgPictureDecoder uses color filter properly', () async { - final PictureInfo info = await svg.svgPictureStringDecoder( - ''' - - - -''', - false, - const ColorFilter.mode(Color(0xFF00FF00), BlendMode.color), - 'test', - ); - final Image image = await info.picture!.toImage(2, 2); - final ByteData data = (await image.toByteData())!; - - const List expected = [ - 0, 48, 0, 255, // - 0, 48, 0, 255, - 0, 48, 0, 255, - 0, 48, 0, 255, - ]; - expect(data.buffer.asUint8List(), expected); - }); - - test('SvgPictureDecoder sets isComplexHint', () async { - final PictureInfo info = await svg.svgPictureStringDecoder( - ''' - - - -''', - false, - null, - 'test', - ); - - expect(info.createLayer().isComplexHint, true); - }); - - test('mergeAndBlend gets strokeWidth right', () async { - final DrawableRoot root = await svg.fromSvgString( - ''' - - - -''', - 'test', - ); - - final DrawablePaint strokePaintA = - (root.children.first as DrawableShape).style.stroke!; - final DrawableRoot mergedRoot = root.mergeStyle( - const DrawableStyle( - stroke: DrawablePaint( - PaintingStyle.stroke, - color: Color(0xFFABCDEF), - ), - ), - ); - - final DrawablePaint strokePaintB = - (mergedRoot.children.first as DrawableShape).style.stroke!; - expect(strokePaintA.strokeWidth, strokePaintB.strokeWidth); - }); - - test('restore canvas accordingly', () async { - const String svgWithViewBox = ''' - - - -'''; - - final PictureRecorder recorder = PictureRecorder(); - final Canvas canvas = Canvas(recorder); - - canvas.save(); - - final DrawableRoot svgRoot = await svg.fromSvgString( - svgWithViewBox, - 'RestoreCanvasWithSvgViewBox', - ); - - svgRoot.scaleCanvasToViewBox(canvas, const Size.square(200)); - svgRoot.clipCanvasToViewBox(canvas); - - svgRoot.draw(canvas, svgRoot.viewport.viewBoxRect); - - expect(canvas.getSaveCount(), equals(2)); - - recorder.endRecording(); - }); - - test('Does not draw if color is null', () async { - final DrawableShape shape = DrawableShape( - 'test', - Path()..addRect(const Rect.fromLTRB(0, 0, 50, 50)), - const DrawableStyle( - fill: DrawablePaint(PaintingStyle.fill), - stroke: DrawablePaint(PaintingStyle.stroke), - ), - ); - - final PathRecordingCanvas canvas = PathRecordingCanvas(); - shape.draw(canvas, Rect.largest); - - expect(canvas.paths.length, 0); - expect(canvas.paints.length, 0); - }); -} - -class PathRecordingCanvas implements Canvas { - final List paths = []; - final List paints = []; - - @override - dynamic noSuchMethod(Invocation invocation) { - if (invocation.memberName == #drawPath) { - paths.add(invocation.positionalArguments.first as Path); - paints.add(invocation.positionalArguments.last as Paint); - return; - } - return super.noSuchMethod(invocation); - } -} diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index c9722652ae94..350234130518 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -1,10 +1,9 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'dart:typed_data'; import 'dart:ui' show window; -import 'package:flutter/rendering.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; @@ -55,8 +54,6 @@ void main() { }); setUp(() { - PictureProvider.cache.clear(); - svg.cacheColorFilterOverride = null; fakeResponse = FakeHttpClientResponse(); fakeRequest = FakeHttpClientRequest(fakeResponse); fakeHttpClient = FakeHttpClient(fakeRequest); @@ -65,7 +62,6 @@ void main() { testWidgets( 'SvgPicture does not use a color filtering widget when no color specified', (WidgetTester tester) async { - expect(PictureProvider.cache.count, 0); await tester.pumpWidget( SvgPicture.string( svgStr, @@ -74,91 +70,8 @@ void main() { ), ); await tester.pumpAndSettle(); - expect(PictureProvider.cache.count, 1); - expect(find.byType(ColorFiltered), findsNothing); - }); - - testWidgets('SvgPicture does not invalidate the cache when color changes', - (WidgetTester tester) async { - expect(PictureProvider.cache.count, 0); - await tester.pumpWidget( - SvgPicture.string( - svgStr, - width: 100.0, - height: 100.0, - color: const Color(0xFF990000), - ), - ); - - expect(PictureProvider.cache.count, 1); - - await tester.pumpWidget( - SvgPicture.string( - svgStr, - width: 100.0, - height: 100.0, - color: const Color(0xFF990099), - ), - ); - - expect(PictureProvider.cache.count, 1); - }); - - testWidgets( - 'SvgPicture does invalidate the cache when color changes and color filter is cached', - (WidgetTester tester) async { - expect(PictureProvider.cache.count, 0); - await tester.pumpWidget( - SvgPicture.string( - svgStr, - width: 100.0, - height: 100.0, - color: const Color(0xFF990000), - cacheColorFilter: true, - ), - ); - - expect(PictureProvider.cache.count, 1); - - await tester.pumpWidget( - SvgPicture.string( - svgStr, - width: 100.0, - height: 100.0, - color: const Color(0xFF990099), - cacheColorFilter: true, - ), - ); - - expect(PictureProvider.cache.count, 2); - }); - - testWidgets( - 'SvgPicture does invalidate the cache when color changes and color filter is cached (override)', - (WidgetTester tester) async { - svg.cacheColorFilterOverride = true; - expect(PictureProvider.cache.count, 0); - await tester.pumpWidget( - SvgPicture.string( - svgStr, - width: 100.0, - height: 100.0, - color: const Color(0xFF990000), - ), - ); - expect(PictureProvider.cache.count, 1); - - await tester.pumpWidget( - SvgPicture.string( - svgStr, - width: 100.0, - height: 100.0, - color: const Color(0xFF990099), - ), - ); - - expect(PictureProvider.cache.count, 2); + expect(find.byType(ColorFiltered), findsNothing); }); testWidgets('SvgPicture can work with a FittedBox', @@ -532,7 +445,10 @@ void main() { svgStr, width: 100.0, height: 100.0, - color: const Color(0xFF990000), + colorFilter: const ColorFilter.mode( + Color(0xFF990000), + BlendMode.srcIn, + ), ), ), ); @@ -551,8 +467,10 @@ void main() { svgStr, width: 100.0, height: 100.0, - color: const Color(0xFF990000), - colorBlendMode: BlendMode.color, + colorFilter: const ColorFilter.mode( + Color(0xFF990000), + BlendMode.color, + ), ), ), ); @@ -585,7 +503,10 @@ void main() { svgData, width: 100.0, height: 100.0, - color: const Color(0xFF990000), + colorFilter: const ColorFilter.mode( + Color(0xFF990000), + BlendMode.srcIn, + ), ), ), ); @@ -594,15 +515,6 @@ void main() { await _checkWidgetAndGolden(key, 'text_color_filter.png'); }); - testWidgets('Nested SVG elements report a FlutterError', - (WidgetTester tester) async { - await svg.fromSvgString( - '', - 'test'); - final UnsupportedError error = tester.takeException() as UnsupportedError; - expect(error.message, 'Unsupported nested element.'); - }); - testWidgets('Can take AlignmentDirectional', (WidgetTester tester) async { await tester.pumpWidget(Directionality( textDirection: TextDirection.ltr, @@ -614,142 +526,6 @@ void main() { expect(find.byType(SvgPicture), findsOneWidget); }); - testWidgets('SvgPicture.string respects clipBehavior', - (WidgetTester tester) async { - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.string(svgStr), - )); - await tester.pumpAndSettle(); - - // Check that the render object has received the default clip behavior. - final RenderFittedBox renderObject = - tester.allRenderObjects.whereType().first; - expect(renderObject.clipBehavior, equals(Clip.hardEdge)); - - // Pump a new widget to check that the render object can update its clip - // behavior. - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.string(svgStr, clipBehavior: Clip.antiAlias), - ), - ); - await tester.pumpAndSettle(); - expect(renderObject.clipBehavior, equals(Clip.antiAlias)); - }); - - testWidgets('SvgPicture.asset respects clipBehavior', - (WidgetTester tester) async { - final FakeAssetBundle fakeAsset = FakeAssetBundle(); - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.asset( - 'test.svg', - bundle: fakeAsset, - ), - )); - await tester.pumpAndSettle(); - - // Check that the render object has received the default clip behavior. - final RenderFittedBox renderObject = - tester.allRenderObjects.whereType().first; - expect(renderObject.clipBehavior, equals(Clip.hardEdge)); - - // Pump a new widget to check that the render object can update its clip - // behavior. - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.asset( - 'test.svg', - bundle: fakeAsset, - clipBehavior: Clip.antiAlias, - ), - ), - ); - await tester.pumpAndSettle(); - expect(renderObject.clipBehavior, equals(Clip.antiAlias)); - }); - - testWidgets('SvgPicture.memory respects clipBehavior', - (WidgetTester tester) async { - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.memory(svgBytes), - )); - await tester.pumpAndSettle(); - - // Check that the render object has received the default clip behavior. - final RenderFittedBox renderObject = - tester.allRenderObjects.whereType().first; - expect(renderObject.clipBehavior, equals(Clip.hardEdge)); - - // Pump a new widget to check that the render object can update its clip - // behavior. - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.memory(svgBytes, clipBehavior: Clip.antiAlias), - ), - ); - await tester.pumpAndSettle(); - expect(renderObject.clipBehavior, equals(Clip.antiAlias)); - }); - - testWidgets('SvgPicture.network respects clipBehavior', - (WidgetTester tester) async { - await HttpOverrides.runZoned(() async { - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.network('test.svg'), - ), - ); - await tester.pumpAndSettle(); - - // Check that the render object has received the default clip behavior. - final RenderFittedBox renderObject = - tester.allRenderObjects.whereType().first; - expect(renderObject.clipBehavior, equals(Clip.hardEdge)); - - // Pump a new widget to check that the render object can update its clip - // behavior. - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.network('test.svg', clipBehavior: Clip.antiAlias), - ), - ); - await tester.pumpAndSettle(); - expect(renderObject.clipBehavior, equals(Clip.antiAlias)); - }, createHttpClient: (SecurityContext? c) => fakeHttpClient); - }); - - testWidgets('SvgPicture respects clipBehavior', (WidgetTester tester) async { - await tester.pumpWidget(Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.string(svgStr), - )); - await tester.pumpAndSettle(); - - // Check that the render object has received the default clip behavior. - final RenderFittedBox renderObject = - tester.allRenderObjects.whereType().first; - expect(renderObject.clipBehavior, equals(Clip.hardEdge)); - - // Pump a new widget to check that the render object can update its clip - // behavior. - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.string(svgStr, clipBehavior: Clip.antiAlias), - ), - ); - await tester.pumpAndSettle(); - expect(renderObject.clipBehavior, equals(Clip.antiAlias)); - }); - group('SvgPicture respects em units', () { testWidgets('circle (cx, cy, r)', (WidgetTester tester) async { final GlobalKey key = GlobalKey(); @@ -870,7 +646,7 @@ void main() { ); await tester.pumpAndSettle(); - await _checkWidgetAndGolden(key, 'circle.em_ex.png'); + await _checkWidgetAndGolden(key, 'circle.em_ex2.png'); }); testWidgets('rect (x, y, width, height, rx, ry)', @@ -897,7 +673,7 @@ void main() { ); await tester.pumpAndSettle(); - await _checkWidgetAndGolden(key, 'rect.em_ex.png'); + await _checkWidgetAndGolden(key, 'rect.em_ex2.png'); }); testWidgets('ellipse (cx, cy, rx, ry)', (WidgetTester tester) async { @@ -923,7 +699,7 @@ void main() { ); await tester.pumpAndSettle(); - await _checkWidgetAndGolden(key, 'ellipse.em_ex.png'); + await _checkWidgetAndGolden(key, 'ellipse.em_ex2.png'); }); testWidgets('line (x1, y1, x2, y2)', (WidgetTester tester) async { @@ -950,7 +726,7 @@ void main() { ); await tester.pumpAndSettle(); - await _checkWidgetAndGolden(key, 'line.em_ex.png'); + await _checkWidgetAndGolden(key, 'line.em_ex2.png'); }); }); @@ -974,113 +750,6 @@ void main() { matchesGoldenFile('golden_widget/two_of_same.png'), ); }); - - testWidgets( - 'Update widget without a cache does not result in an disposed picture', - (WidgetTester tester) async { - final int oldCacheSize = PictureProvider.cache.maximumSize; - PictureProvider.cache.maximumSize = 0; - final GlobalKey key = GlobalKey(); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture( - FakePictureProvider( - SvgPicture.svgStringDecoderBuilder, - simpleSvg, - ), - key: key), - ), - ); - - expect(find.byKey(key), findsOneWidget); - - // Update the widget with a new incompatible key. - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture( - FakePictureProvider( - SvgPicture.svgStringDecoderBuilder, - stickFigureSvgStr, - ), - key: key), - ), - ); - - expect(find.byKey(key), findsOneWidget); - await tester.pumpAndSettle(); - PictureProvider.cache.maximumSize = oldCacheSize; - }); - - testWidgets('state maintains a handle', (WidgetTester tester) async { - final int oldCacheSize = PictureProvider.cache.maximumSize; - PictureProvider.cache.maximumSize = 1; - final GlobalKey key = GlobalKey(); - final FakePictureProvider provider = FakePictureProvider( - SvgPicture.svgStringDecoderBuilder, - simpleSvg, - ); - - final PictureStream stream = provider.resolve( - createLocalPictureConfiguration(key.currentContext), - ); - final Completer completer = Completer(); - void listener(PictureInfo? info, bool syncCall) { - completer.complete(info!); - } - - stream.addListener(listener); - - final PictureInfo info = await completer.future; - expect(info.debugHandleCount, 1); - stream.removeListener(listener); - // Still in cache. - expect(info.debugHandleCount, 1); - - await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture(provider, key: key), - ), - ); - expect(find.byKey(key), findsOneWidget); - expect(info.debugHandleCount, 3); - PictureProvider.cache.clear(); - expect(info.debugHandleCount, 3); - - await tester.pumpWidget(const SizedBox.shrink()); - expect(info.debugHandleCount, 0); - - PictureProvider.cache.maximumSize = oldCacheSize; - }); -} - -class FakePictureProvider extends StringPicture { - FakePictureProvider( - PictureInfoDecoderBuilder decoderBuilder, - String string, - ) : super(decoderBuilder, string); - - int resolveCount = 0; - - @override - PictureStream resolve( - PictureConfiguration picture, { - PictureErrorListener? onError, - }) { - resolveCount += 1; - return super.resolve(picture, onError: onError); - } - - @override - // ignore: hash_and_equals, avoid_equals_and_hash_code_on_mutable_classes - bool operator ==(Object other) { - // Picture providers should be compared based on key. Make sure tests don't - // cheat this check by using an identical provider. - return false; - } } class FakeAssetBundle extends Fake implements AssetBundle { @@ -1088,6 +757,11 @@ class FakeAssetBundle extends Fake implements AssetBundle { Future loadString(String key, {bool cache = true}) async { return svgStr; } + + @override + Future load(String key) async { + return Uint8List.fromList(utf8.encode(svgStr)).buffer.asByteData(); + } } class FakeHttpClient extends Fake implements HttpClient { diff --git a/third_party/test/xml_svg_test.dart b/third_party/test/xml_svg_test.dart deleted file mode 100644 index 2d8992cb0209..000000000000 --- a/third_party/test/xml_svg_test.dart +++ /dev/null @@ -1,435 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter_svg/flutter_svg.dart'; -import 'package:flutter_svg/src/svg/parser_state.dart'; -import 'package:flutter_svg/src/utilities/xml.dart'; -import 'package:path_drawing/path_drawing.dart'; -import 'package:test/test.dart'; -import 'package:xml/xml_events.dart'; - -class TestSvgParserState extends SvgParserState { - TestSvgParserState({double fontSize = 14, double? xHeight}) - : super( - [], - SvgTheme(fontSize: fontSize, xHeight: xHeight), - 'testKey', - false, - ); - - @override - late Map attributes; -} - -void main() { - test('Xlink href tests', () { - final XmlStartElementEvent el = - parseEvents('').first - as XmlStartElementEvent; - - final XmlStartElementEvent elXlink = - parseEvents('') - .first as XmlStartElementEvent; - - expect( - getHrefAttribute(el.attributes.toAttributeMap()), 'http://localhost'); - expect(getHrefAttribute(elXlink.attributes.toAttributeMap()), - 'http://localhost'); - }); - - test('Attribute and style tests', () { - final XmlStartElementEvent el = - parseEvents('') - .first as XmlStartElementEvent; - - final Map attributes = el.attributes.toAttributeMap(); - expect(getAttribute(attributes, 'stroke'), '#fff'); - expect(getAttribute(attributes, 'fill'), '#eee'); - expect(getAttribute(attributes, 'stroke-dashpattern'), '1 2'); - expect(getAttribute(attributes, 'stroke-opacity'), '1'); - expect(getAttribute(attributes, 'stroke-another'), ''); - expect(getAttribute(attributes, 'fill-opacity'), '.23'); - - expect(getAttribute(attributes, 'fill-opacity', checkStyle: false), ''); - expect(getAttribute(attributes, 'fill', checkStyle: false), '#eee'); - }); - - // if the parsing logic changes, we can simplify some methods. for now assert that whitespace in attributes is preserved - test('Attribute WhiteSpace test', () { - final XmlStartElementEvent xd = - parseEvents('').first - as XmlStartElementEvent; - - expect( - xd.attributes[0].value, - ' asdf', - reason: - 'XML Parsing implementation no longer preserves leading whitespace in attributes!', - ); - expect( - xd.attributes[1].value, - 'asdf ', - reason: - 'XML Parsing implementation no longer preserves trailing whitespace in attributes!', - ); - }); - - test('viewBox tests', () { - const Rect rect = Rect.fromLTWH(0.0, 0.0, 100.0, 100.0); - - final XmlStartElementEvent svgWithViewBox = - parseEvents('').first - as XmlStartElementEvent; - final XmlStartElementEvent svgWithViewBoxAndWidthHeight = - parseEvents('') - .first as XmlStartElementEvent; - final XmlStartElementEvent svgWithWidthHeight = - parseEvents('').first - as XmlStartElementEvent; - final XmlStartElementEvent svgWithViewBoxMinXMinY = - parseEvents('').first - as XmlStartElementEvent; - final XmlStartElementEvent svgWithNoSizeInfo = - parseEvents('').first as XmlStartElementEvent; - - final TestSvgParserState parserState = TestSvgParserState(); - - parserState.attributes = - svgWithViewBoxAndWidthHeight.attributes.toAttributeMap(); - expect(parserState.parseViewBox()!.size, const Size(50, 50)); - - parserState.attributes = svgWithViewBox.attributes.toAttributeMap(); - expect(parserState.parseViewBox()!.viewBoxRect, rect); - - parserState.attributes = svgWithViewBox.attributes.toAttributeMap(); - expect(parserState.parseViewBox()!.viewBoxOffset, Offset.zero); - - parserState.attributes = - svgWithViewBoxAndWidthHeight.attributes.toAttributeMap(); - expect(parserState.parseViewBox()!.viewBoxRect, rect); - - parserState.attributes = svgWithWidthHeight.attributes.toAttributeMap(); - expect(parserState.parseViewBox()!.viewBoxRect, rect); - - parserState.attributes = svgWithNoSizeInfo.attributes.toAttributeMap(); - expect(parserState.parseViewBox(nullOk: true), null); - - parserState.attributes = svgWithNoSizeInfo.attributes.toAttributeMap(); - expect(() => parserState.parseViewBox(), throwsStateError); - - parserState.attributes = svgWithViewBoxMinXMinY.attributes.toAttributeMap(); - expect(parserState.parseViewBox()!.viewBoxRect, rect); - - parserState.attributes = svgWithViewBoxMinXMinY.attributes.toAttributeMap(); - expect( - parserState.parseViewBox()!.viewBoxOffset, - const Offset(-42.0, -56.0), - ); - }); - - test('TileMode tests', () { - final XmlStartElementEvent pad = - parseEvents('').first - as XmlStartElementEvent; - final XmlStartElementEvent reflect = - parseEvents('').first - as XmlStartElementEvent; - final XmlStartElementEvent repeat = - parseEvents('').first - as XmlStartElementEvent; - final XmlStartElementEvent invalid = - parseEvents('').first - as XmlStartElementEvent; - - final XmlStartElementEvent none = - parseEvents('').first as XmlStartElementEvent; - - final TestSvgParserState parserState = TestSvgParserState(); - parserState.attributes = pad.attributes.toAttributeMap(); - expect(parserState.parseTileMode(), TileMode.clamp); - - parserState.attributes = invalid.attributes.toAttributeMap(); - expect(parserState.parseTileMode(), TileMode.clamp); - - parserState.attributes = none.attributes.toAttributeMap(); - expect(parserState.parseTileMode(), TileMode.clamp); - - parserState.attributes = reflect.attributes.toAttributeMap(); - expect(parserState.parseTileMode(), TileMode.mirror); - - parserState.attributes = repeat.attributes.toAttributeMap(); - expect(parserState.parseTileMode(), TileMode.repeated); - }); - - test('@stroke-dashoffset tests', () { - final XmlStartElementEvent abs = - parseEvents('').first - as XmlStartElementEvent; - final XmlStartElementEvent pct = - parseEvents('').first - as XmlStartElementEvent; - - final TestSvgParserState parserState = TestSvgParserState(); - parserState.attributes = abs.attributes.toAttributeMap(); - expect( - parserState.parseDashOffset(), - equals(const DashOffset.absolute(20.0)), - ); - - parserState.attributes = pct.attributes.toAttributeMap(); - expect( - parserState.parseDashOffset(), - equals(DashOffset.percentage(0.2)), - ); - }); - - test('font-weight tests', () { - final TestSvgParserState parserState = TestSvgParserState(); - expect(parserState.parseFontWeight('100'), FontWeight.w100); - expect(parserState.parseFontWeight('200'), FontWeight.w200); - expect(parserState.parseFontWeight('300'), FontWeight.w300); - expect(parserState.parseFontWeight('400'), FontWeight.w400); - expect(parserState.parseFontWeight('500'), FontWeight.w500); - expect(parserState.parseFontWeight('600'), FontWeight.w600); - expect(parserState.parseFontWeight('700'), FontWeight.w700); - expect(parserState.parseFontWeight('800'), FontWeight.w800); - expect(parserState.parseFontWeight('900'), FontWeight.w900); - - expect(parserState.parseFontWeight('normal'), FontWeight.normal); - expect(parserState.parseFontWeight('bold'), FontWeight.bold); - - expect( - () => parserState.parseFontWeight('invalid'), throwsUnsupportedError); - }); - - test('font-style tests', () { - final TestSvgParserState parserState = TestSvgParserState(); - expect(parserState.parseFontStyle('normal'), FontStyle.normal); - expect(parserState.parseFontStyle('italic'), FontStyle.italic); - expect(parserState.parseFontStyle('oblique'), FontStyle.italic); - - expect(parserState.parseFontStyle(null), isNull); - expect(() => parserState.parseFontStyle('invalid'), throwsUnsupportedError); - }); - - test('text-decoration tests', () { - final TestSvgParserState parserState = TestSvgParserState(); - expect(parserState.parseTextDecoration('none'), TextDecoration.none); - expect(parserState.parseTextDecoration('line-through'), - TextDecoration.lineThrough); - expect( - parserState.parseTextDecoration('overline'), TextDecoration.overline); - expect( - parserState.parseTextDecoration('underline'), TextDecoration.underline); - - expect(parserState.parseTextDecoration(null), isNull); - expect(() => parserState.parseTextDecoration('invalid'), - throwsUnsupportedError); - }); - - test('text-decoration-style tests', () { - final TestSvgParserState parserState = TestSvgParserState(); - expect(parserState.parseTextDecorationStyle('solid'), - TextDecorationStyle.solid); - expect(parserState.parseTextDecorationStyle('dashed'), - TextDecorationStyle.dashed); - expect(parserState.parseTextDecorationStyle('dotted'), - TextDecorationStyle.dotted); - expect(parserState.parseTextDecorationStyle('double'), - TextDecorationStyle.double); - expect( - parserState.parseTextDecorationStyle('wavy'), TextDecorationStyle.wavy); - - expect(parserState.parseTextDecorationStyle(null), isNull); - expect(() => parserState.parseTextDecorationStyle('invalid'), - throwsUnsupportedError); - }); - - group('parseStyle', () { - test('uses currentColor for stroke color', () { - const Color currentColor = Color(0xFFB0E3BE); - final XmlStartElementEvent svg = - parseEvents('').first - as XmlStartElementEvent; - - final TestSvgParserState parserState = TestSvgParserState(); - parserState.attributes = svg.attributes.toAttributeMap(); - final DrawableStyle svgStyle = parserState.parseStyle( - Rect.zero, - null, - currentColor: currentColor, - ); - - expect( - svgStyle.stroke?.color, - equals(currentColor), - ); - }); - - test('uses currentColor for fill color', () { - const Color currentColor = Color(0xFFB0E3BE); - final XmlStartElementEvent svg = - parseEvents('').first - as XmlStartElementEvent; - - final TestSvgParserState parserState = TestSvgParserState(); - parserState.attributes = svg.attributes.toAttributeMap(); - final DrawableStyle svgStyle = parserState.parseStyle( - Rect.zero, - null, - currentColor: currentColor, - ); - - expect( - svgStyle.fill?.color, - equals(currentColor), - ); - }); - - group('calculates em units based on the font size for', () { - test('stroke width', () { - final XmlStartElementEvent svg = - parseEvents('').first - as XmlStartElementEvent; - - const double fontSize = 26.0; - - final TestSvgParserState parserState = TestSvgParserState( - fontSize: fontSize, - ); - parserState.attributes = svg.attributes.toAttributeMap(); - final DrawableStyle svgStyle = parserState.parseStyle(Rect.zero, null); - - expect( - svgStyle.stroke?.strokeWidth, - equals(fontSize * 2), - ); - }); - - test('dash array', () { - final XmlStartElementEvent svg = parseEvents( - '', - ).first as XmlStartElementEvent; - - const double fontSize = 26.0; - - final TestSvgParserState parserState = TestSvgParserState( - fontSize: fontSize, - ); - parserState.attributes = svg.attributes.toAttributeMap(); - final DrawableStyle svgStyle = parserState.parseStyle(Rect.zero, null); - - expect( - [ - svgStyle.dashArray!.next, - svgStyle.dashArray!.next, - svgStyle.dashArray!.next, - ], - equals([ - fontSize * 0.2, - fontSize * 0.5, - 10, - ]), - ); - }); - - test('dash offset', () { - final XmlStartElementEvent svg = parseEvents( - '', - ).first as XmlStartElementEvent; - - const double fontSize = 26.0; - - final TestSvgParserState parserState = TestSvgParserState( - fontSize: fontSize, - ); - parserState.attributes = svg.attributes.toAttributeMap(); - final DrawableStyle svgStyle = parserState.parseStyle(Rect.zero, null); - - expect( - svgStyle.dashOffset, - equals(const DashOffset.absolute(fontSize * 0.15)), - ); - }); - }); - - group('calculates ex units based on the x-height for', () { - test('stroke width', () { - final XmlStartElementEvent svg = - parseEvents('').first - as XmlStartElementEvent; - - const double fontSize = 26.0; - const double xHeight = 11.0; - - final TestSvgParserState parserState = TestSvgParserState( - fontSize: fontSize, - xHeight: xHeight, - ); - parserState.attributes = svg.attributes.toAttributeMap(); - final DrawableStyle svgStyle = parserState.parseStyle(Rect.zero, null); - - expect( - svgStyle.stroke?.strokeWidth, - equals(xHeight * 2), - ); - }); - - test('dash array', () { - final XmlStartElementEvent svg = parseEvents( - '', - ).first as XmlStartElementEvent; - - const double fontSize = 26.0; - const double xHeight = 11.0; - - final TestSvgParserState parserState = TestSvgParserState( - fontSize: fontSize, - xHeight: xHeight, - ); - parserState.attributes = svg.attributes.toAttributeMap(); - final DrawableStyle svgStyle = parserState.parseStyle(Rect.zero, null); - - expect( - [ - svgStyle.dashArray!.next, - svgStyle.dashArray!.next, - svgStyle.dashArray!.next, - ], - equals([ - xHeight * 0.2, - xHeight * 0.5, - 10, - ]), - ); - }); - - test('dash offset', () { - final XmlStartElementEvent svg = parseEvents( - '', - ).first as XmlStartElementEvent; - - const double fontSize = 26.0; - const double xHeight = 11.0; - - final TestSvgParserState parserState = TestSvgParserState( - fontSize: fontSize, - xHeight: xHeight, - ); - parserState.attributes = svg.attributes.toAttributeMap(); - final DrawableStyle svgStyle = parserState.parseStyle(Rect.zero, null); - - expect( - svgStyle.dashOffset, - equals(const DashOffset.absolute(xHeight * 0.15)), - ); - }); - }); - }); - - test('Handles pt values', () { - final TestSvgParserState state = TestSvgParserState(); - expect(state.parseDoubleWithUnits('1pt'), 1 + 1 / 3); - }); -} diff --git a/third_party/tool/gen_golden.dart b/third_party/tool/gen_golden.dart deleted file mode 100644 index 80f4faff5555..000000000000 --- a/third_party/tool/gen_golden.dart +++ /dev/null @@ -1,86 +0,0 @@ -// There's probably some better way to do this, but for now run `flutter test tool/gen_golden.dart -// should exclude files that -// - aren't rendering properly -// - have text (this doesn't render properly in the host setup?) -// The golden files should then be visually compared against Chrome's rendering output for correctness. -// The comparison may have to be made more tolerant if we want to use other sources of rendering for comparison... - -import 'dart:io'; -import 'dart:typed_data'; -import 'dart:ui'; - -import 'package:flutter_svg/src/vector_drawable.dart'; -import 'package:flutter_svg/svg.dart'; -import 'package:path/path.dart' as path; - -Future getSvgImage(String svgData) async { - final PictureRecorder rec = PictureRecorder(); - final Canvas canvas = Canvas(rec); - - const Size size = Size(200.0, 200.0); - - final DrawableRoot svgRoot = await svg.fromSvgString( - svgData, - 'GenGoldenTest', - ); - - svgRoot.scaleCanvasToViewBox(canvas, size); - svgRoot.clipCanvasToViewBox(canvas); - - canvas.drawPaint(Paint()..color = const Color(0xFFFFFFFF)); - svgRoot.draw(canvas, svgRoot.viewport.viewBoxRect); - - final Picture pict = rec.endRecording(); - - return await pict.toImage(size.width.toInt(), size.height.toInt()); -} - -Future getSvgPngBytes(String svgData) async { - final Image image = await getSvgImage(svgData); - final ByteData bytes = (await image.toByteData(format: ImageByteFormat.png))!; - - return bytes.buffer.asUint8List(); -} - -Future getSvgRgbaBytes(String svgData) async { - final Image image = await getSvgImage(svgData); - final ByteData bytes = - (await image.toByteData(format: ImageByteFormat.rawRgba))!; - - return bytes.buffer.asUint8List(); -} - -Iterable getSvgFileNames() sync* { - final Directory dir = Directory('./example/assets'); - for (FileSystemEntity fe in dir.listSync(recursive: true)) { - if (fe is File && fe.path.toLowerCase().endsWith('.svg')) { - // Skip text based tests unless we're on Linux - these have - // subtle platform specific differences. - if (fe.path.toLowerCase().contains('text') && !Platform.isLinux) { - continue; - } - yield fe; - } - } -} - -String getGoldenFileName(String svgAssetPath) { - return svgAssetPath - .replaceAll('/example\/assets/', '/golden/') - .replaceAll('\\example\\assets\\', '\\golden\\') - .replaceAll('.svg', '.png'); -} - -Future main() async { - for (File fe in getSvgFileNames()) { - final String pathName = getGoldenFileName(fe.path); - - final Directory goldenDir = Directory(path.dirname(pathName)); - if (!goldenDir.existsSync()) { - goldenDir.createSync(recursive: true); - } - final File output = File(pathName); - print(pathName); - await output.writeAsBytes(await getSvgPngBytes(await fe.readAsString())); - } -} From 857527280b266774ad8e052521c69dafe5dd1a2f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 21 Nov 2022 09:27:57 -0800 Subject: [PATCH 464/512] Drop unused deps (#808) * Drop unnecessary deps * Remove unused deps * MORE --- third_party/pubspec.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index f13af394a833..5b767ef30ef7 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -7,18 +7,13 @@ version: 2.0.0 dependencies: flutter: sdk: flutter - meta: ^1.7.0 - path_drawing: ^1.0.1 vector_graphics: ^1.0.0 vector_graphics_codec: ^1.0.0 vector_graphics_compiler: ^1.0.0 - vector_math: ^2.1.2 dev_dependencies: flutter_test: sdk: flutter - path: ^1.8.1 - test: ^1.21.1 environment: sdk: '>=2.17.0 <3.0.0' From 2bfb5e89e92b598957e20da737e6af59bb932749 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Fri, 9 Dec 2022 18:25:07 -0800 Subject: [PATCH 465/512] update readme to add more details about precompiliation (#816) * update readme * update versions for prelease and remove unused code * re-word and combine --- third_party/CHANGELOG.md | 2 +- third_party/lib/src/utilities/xml.dart | 69 -------------------------- third_party/pubspec.yaml | 6 +-- 3 files changed, 4 insertions(+), 73 deletions(-) delete mode 100644 third_party/lib/src/utilities/xml.dart diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 630117fccb22..4964bf39ece5 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGES -## 2.0.0 +## 2.0.0-dev.1 - Use parsing backend from `vector_graphics_compiler`. - Out of order defs now supported. diff --git a/third_party/lib/src/utilities/xml.dart b/third_party/lib/src/utilities/xml.dart deleted file mode 100644 index 61a57cf6220d..000000000000 --- a/third_party/lib/src/utilities/xml.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:xml/xml_events.dart'; - -/// The namespace for xlink from the SVG 1.1 spec. -const String kXlinkNamespace = 'http://www.w3.org/1999/xlink'; - -/// Get the `xlink:href` or `href` attribute, preferring `xlink`. -/// -/// SVG 1.1 specifies that these attributes should be in the xlink namespace. -/// SVG 2 deprecates that namespace. -String? getHrefAttribute(Map attributes) => getAttribute( - attributes, - 'href', - def: getAttribute(attributes, 'href'), - ); - -/// Gets the attribute, trims it, and returns the attribute or default if the attribute -/// is null or ''. -/// -/// Will look to the style first if it can. -String? getAttribute( - Map el, - String name, { - String? def = '', - bool checkStyle = true, -}) { - String raw = ''; - if (checkStyle) { - final String? style = _getAttribute(el, 'style'); - if (style != '' && style != null) { - // Probably possible to slightly optimize this (e.g. use indexOf instead of split), - // but handling potential whitespace will get complicated and this just works. - // I also don't feel like writing benchmarks for what is likely a micro-optimization. - final List styles = style.split(';'); - raw = styles.firstWhere( - (String str) => str.trimLeft().startsWith(name + ':'), - orElse: () => ''); - - if (raw != '') { - raw = raw.substring(raw.indexOf(':') + 1).trim(); - } - } - - if (raw == '') { - raw = _getAttribute(el, name); - } - } else { - raw = _getAttribute(el, name); - } - - return raw == '' ? def : raw; -} - -String _getAttribute( - Map attributes, - String localName, { - String def = '', -}) { - return attributes[localName] ?? def; -} - -/// Extension on List for easy conversion to an attribute -/// map. -extension AttributeMapXmlEventAttributeExtension on List { - /// Converts the List to an attribute map. - Map toAttributeMap() => { - for (final XmlEventAttribute attribute in this) - attribute.localName: attribute.value.trim(), - }; -} diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 5b767ef30ef7..db9b93234520 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.0 +version: 2.0.0-dev.1 dependencies: flutter: @@ -16,8 +16,8 @@ dev_dependencies: sdk: flutter environment: - sdk: '>=2.17.0 <3.0.0' - flutter: ">=3.4.0-34.1.pre" + sdk: '>=2.19.0-0 <3.0.0' + flutter: ">=3.7.0-0" # dependency_overrides: # vector_graphics: From 3b8f0a08b547beb8c1accc3e7e4c7f11783193dc Mon Sep 17 00:00:00 2001 From: Dan Field Date: Sun, 11 Dec 2022 14:27:31 -0800 Subject: [PATCH 466/512] Avoid anon closure (#817) --- third_party/lib/src/loaders.dart | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/third_party/lib/src/loaders.dart b/third_party/lib/src/loaders.dart index 81750c3ef705..dac70c4ca6f2 100644 --- a/third_party/lib/src/loaders.dart +++ b/third_party/lib/src/loaders.dart @@ -35,25 +35,27 @@ abstract class SvgLoader extends BytesLoader { Future prepareMessage(BuildContext? context) => SynchronousFuture(null); + Future _load(BuildContext? context) { + return prepareMessage(context).then((T? message) { + return compute((T? message) { + return encodeSvg( + xml: provideSvg(message), + theme: theme, + colorMapper: colorMapper, + debugName: 'Svg loader', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ).buffer.asByteData(); + }, message, debugLabel: 'Load Bytes'); + }); + } + /// This method intentionally avoids using `await` to avoid unnecessary event /// loop turns. This is meant to to help tests in particular. @override Future loadBytes(BuildContext? context) { - return svg.cache.putIfAbsent(cacheKey(context), () { - return prepareMessage(context).then((T? message) { - return compute((T? message) { - return encodeSvg( - xml: provideSvg(message), - theme: theme, - colorMapper: colorMapper, - debugName: 'Svg loader', - enableClippingOptimizer: false, - enableMaskingOptimizer: false, - enableOverdrawOptimizer: false, - ).buffer.asByteData(); - }, message, debugLabel: 'Load Bytes'); - }); - }); + return svg.cache.putIfAbsent(cacheKey(context), () => _load(context)); } } From e92e719ba4be1e3c63e245c5cf2d8d2f5e4d72d1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 20 Jan 2023 11:01:22 -0800 Subject: [PATCH 467/512] more --- third_party/example/pubspec.yaml | 14 +++++++------- third_party/pubspec.yaml | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/third_party/example/pubspec.yaml b/third_party/example/pubspec.yaml index a4f3c406da1a..6cfa385ab38c 100644 --- a/third_party/example/pubspec.yaml +++ b/third_party/example/pubspec.yaml @@ -30,10 +30,10 @@ environment: sdk: '>=2.17.0-0 <3.0.0' flutter: ">=3.4.0-34.1.pre" -# dependency_overrides: -# vector_graphics_codec: -# path: ../../vector_graphics/packages/vector_graphics_codec -# vector_graphics_compiler: -# path: ../../vector_graphics/packages/vector_graphics_compiler -# vector_graphics: -# path: ../../vector_graphics/packages/vector_graphics +dependency_overrides: + vector_graphics_codec: + path: ../../vector_graphics/packages/vector_graphics_codec + vector_graphics_compiler: + path: ../../vector_graphics/packages/vector_graphics_compiler + vector_graphics: + path: ../../vector_graphics/packages/vector_graphics diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index db9b93234520..73fe557aef1f 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,14 +2,14 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.0-dev.1 +version: 2.0.0-dev.2 dependencies: flutter: sdk: flutter - vector_graphics: ^1.0.0 - vector_graphics_codec: ^1.0.0 - vector_graphics_compiler: ^1.0.0 + vector_graphics: ^1.0.0+1 + vector_graphics_codec: ^1.0.0+1 + vector_graphics_compiler: ^1.0.0+1 dev_dependencies: flutter_test: From 0fe50dd6f7c453631841096d6216d9fafb89677f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 20 Jan 2023 11:06:34 -0800 Subject: [PATCH 468/512] fix pubspec --- third_party/example/pubspec.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/third_party/example/pubspec.yaml b/third_party/example/pubspec.yaml index 6cfa385ab38c..a4f3c406da1a 100644 --- a/third_party/example/pubspec.yaml +++ b/third_party/example/pubspec.yaml @@ -30,10 +30,10 @@ environment: sdk: '>=2.17.0-0 <3.0.0' flutter: ">=3.4.0-34.1.pre" -dependency_overrides: - vector_graphics_codec: - path: ../../vector_graphics/packages/vector_graphics_codec - vector_graphics_compiler: - path: ../../vector_graphics/packages/vector_graphics_compiler - vector_graphics: - path: ../../vector_graphics/packages/vector_graphics +# dependency_overrides: +# vector_graphics_codec: +# path: ../../vector_graphics/packages/vector_graphics_codec +# vector_graphics_compiler: +# path: ../../vector_graphics/packages/vector_graphics_compiler +# vector_graphics: +# path: ../../vector_graphics/packages/vector_graphics From 78dc13ea229b8a0c645a71ae95d7f31140d79c3a Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 20 Jan 2023 11:09:05 -0800 Subject: [PATCH 469/512] readme --- third_party/CHANGELOG.md | 4 +++- third_party/pubspec.yaml | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 4964bf39ece5..8094075ecdb0 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGES -## 2.0.0-dev.1 +## 2.0.0 - Use parsing backend from `vector_graphics_compiler`. - Out of order defs now supported. @@ -24,6 +24,8 @@ - The `PicturePovider` class exists only for access to a no-op cache. - Several static members on `SvgPicture` and the `svg` utility class have gone away. +- The `color` and `colorBlendMode` properties have been removed. Instead, use + the `colorFilter` property instead. ## 1.1.6 diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 73fe557aef1f..0d5a9fedb3f4 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.0-dev.2 +version: 2.0.0 dependencies: flutter: From 4ec85378df67c285d6901f93b25f9f93e0eb89a5 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 2 Feb 2023 09:53:16 -0800 Subject: [PATCH 470/512] bumps --- third_party/pubspec.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 0d5a9fedb3f4..2d4a11f8e70d 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -7,17 +7,17 @@ version: 2.0.0 dependencies: flutter: sdk: flutter - vector_graphics: ^1.0.0+1 - vector_graphics_codec: ^1.0.0+1 - vector_graphics_compiler: ^1.0.0+1 + vector_graphics: ^1.0.1 + vector_graphics_codec: ^1.0.1 + vector_graphics_compiler: ^1.0.1 dev_dependencies: flutter_test: sdk: flutter environment: - sdk: '>=2.19.0-0 <3.0.0' - flutter: ">=3.7.0-0" + sdk: '>=2.19.0 <3.0.0' + flutter: ">=3.7.0" # dependency_overrides: # vector_graphics: From e8ec6c387bf6291c03c7c612dc8efcd2d42e95bd Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 2 Feb 2023 09:57:59 -0800 Subject: [PATCH 471/512] Fix CI --- third_party/CHANGELOG.md | 2 +- third_party/pubspec.yaml | 2 +- third_party/test/widget_svg_test.dart | 22 +++++++++++----------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 8094075ecdb0..944ed054bf29 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -25,7 +25,7 @@ - Several static members on `SvgPicture` and the `svg` utility class have gone away. - The `color` and `colorBlendMode` properties have been removed. Instead, use - the `colorFilter` property instead. + the `colorFilter` property. ## 1.1.6 diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 2d4a11f8e70d..938f3a1b0f17 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -16,7 +16,7 @@ dev_dependencies: sdk: flutter environment: - sdk: '>=2.19.0 <3.0.0' + sdk: '>=2.19.0-0 <3.0.0' flutter: ">=3.7.0" # dependency_overrides: diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index 350234130518..efa5c0536b1c 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -107,7 +107,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: RepaintBoundary( key: key, child: SvgPicture.string( @@ -127,7 +127,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: Center( key: key, child: SvgPicture.string( @@ -145,7 +145,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: Center( key: key, child: SvgPicture.string( @@ -163,7 +163,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: RepaintBoundary( key: key, child: Directionality( @@ -204,7 +204,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: RepaintBoundary( key: key, child: Directionality( @@ -245,7 +245,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: RepaintBoundary( key: key, child: SvgPicture.memory( @@ -264,7 +264,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: RepaintBoundary( key: key, child: SvgPicture.asset( @@ -286,7 +286,7 @@ void main() { Directionality( textDirection: TextDirection.ltr, child: MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: DefaultAssetBundle( bundle: fakeAsset, child: RepaintBoundary( @@ -309,7 +309,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: RepaintBoundary( key: key, child: SvgPicture.network( @@ -328,7 +328,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: RepaintBoundary( key: key, child: SvgPicture.network('test.svg', @@ -365,7 +365,7 @@ void main() { fakeResponse.statusCode = 400; await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: MediaQueryData.fromView(window), child: SvgPicture.network( 'notFound.svg', ), From 8e62b6bed8ee3cba17cfc4a7b617f84ba4ec5d6a Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 2 Feb 2023 10:02:09 -0800 Subject: [PATCH 472/512] more --- third_party/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 938f3a1b0f17..75ba02faad5f 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -16,8 +16,8 @@ dev_dependencies: sdk: flutter environment: - sdk: '>=2.19.0-0 <3.0.0' - flutter: ">=3.7.0" + sdk: '>=2.19.0-0 <4.0.0' + flutter: ">=3.7.0-0" # dependency_overrides: # vector_graphics: From 97d8e148731aea11949203f7b6061ab8793aa871 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 2 Feb 2023 10:18:43 -0800 Subject: [PATCH 473/512] Fix CI (#835) --- third_party/test/widget_svg_test.dart | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/third_party/test/widget_svg_test.dart b/third_party/test/widget_svg_test.dart index efa5c0536b1c..350234130518 100644 --- a/third_party/test/widget_svg_test.dart +++ b/third_party/test/widget_svg_test.dart @@ -107,7 +107,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: RepaintBoundary( key: key, child: SvgPicture.string( @@ -127,7 +127,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: Center( key: key, child: SvgPicture.string( @@ -145,7 +145,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: Center( key: key, child: SvgPicture.string( @@ -163,7 +163,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: RepaintBoundary( key: key, child: Directionality( @@ -204,7 +204,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: RepaintBoundary( key: key, child: Directionality( @@ -245,7 +245,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: RepaintBoundary( key: key, child: SvgPicture.memory( @@ -264,7 +264,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: RepaintBoundary( key: key, child: SvgPicture.asset( @@ -286,7 +286,7 @@ void main() { Directionality( textDirection: TextDirection.ltr, child: MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: DefaultAssetBundle( bundle: fakeAsset, child: RepaintBoundary( @@ -309,7 +309,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: RepaintBoundary( key: key, child: SvgPicture.network( @@ -328,7 +328,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: RepaintBoundary( key: key, child: SvgPicture.network('test.svg', @@ -365,7 +365,7 @@ void main() { fakeResponse.statusCode = 400; await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromView(window), + data: MediaQueryData.fromWindow(window), child: SvgPicture.network( 'notFound.svg', ), From 70c14b6bb93d8dfd493e870ed4773259d4aea7c7 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 2 Feb 2023 22:06:49 -0800 Subject: [PATCH 474/512] Packages (#838) --- third_party/CHANGELOG.md | 4 ++++ third_party/lib/src/loaders.dart | 4 +++- third_party/pubspec.yaml | 2 +- third_party/test/loaders_test.dart | 26 ++++++++++++++++++++++++-- 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 944ed054bf29..5578c9834802 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 2.0.0+1 + +- Fix bug in asset loading from packages. + ## 2.0.0 - Use parsing backend from `vector_graphics_compiler`. diff --git a/third_party/lib/src/loaders.dart b/third_party/lib/src/loaders.dart index dac70c4ca6f2..d7d456f7d2d2 100644 --- a/third_party/lib/src/loaders.dart +++ b/third_party/lib/src/loaders.dart @@ -213,7 +213,9 @@ class SvgAssetLoader extends SvgLoader { @override Future prepareMessage(BuildContext? context) { - return _resolveBundle(context).load(assetName); + return _resolveBundle(context).load( + packageName == null ? assetName : 'packages/$packageName/$assetName', + ); } @override diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 75ba02faad5f..845cd1356cd5 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.0 +version: 2.0.0+1 dependencies: flutter: diff --git a/third_party/test/loaders_test.dart b/third_party/test/loaders_test.dart index 39c748a0a097..46fafe1e0650 100644 --- a/third_party/test/loaders_test.dart +++ b/third_party/test/loaders_test.dart @@ -1,5 +1,4 @@ -import 'dart:typed_data'; - +import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -19,6 +18,29 @@ void main() { expect(identical(bytes, bytes2), false); svg.cache.maximumSize = 100; }); + + test('AssetLoader respects packages', () async { + final TestBundle bundle = TestBundle({ + 'foo': Uint8List(0).buffer.asByteData(), + 'packages/packageName/foo': Uint8List(1).buffer.asByteData(), + }); + final SvgAssetLoader loader = SvgAssetLoader('foo', assetBundle: bundle); + final SvgAssetLoader packageLoader = + SvgAssetLoader('foo', assetBundle: bundle, packageName: 'packageName'); + expect((await loader.prepareMessage(null))!.lengthInBytes, 0); + expect((await packageLoader.prepareMessage(null))!.lengthInBytes, 1); + }); +} + +class TestBundle extends Fake implements AssetBundle { + TestBundle(this.map); + + final Map map; + + @override + Future load(String key) async { + return map[key]!; + } } class TestLoader extends SvgLoader { From 823a7517c68cf1b6647f219603107b5247e05225 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 6 Feb 2023 11:14:33 -0800 Subject: [PATCH 475/512] fix gradle versions --- third_party/example/android/build.gradle | 2 +- .../example/android/gradle/wrapper/gradle-wrapper.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/example/android/build.gradle b/third_party/example/android/build.gradle index 44f45cd3a803..e688f0a6933a 100644 --- a/third_party/example/android/build.gradle +++ b/third_party/example/android/build.gradle @@ -8,7 +8,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:4.1.0' + classpath 'com.android.tools.build:gradle:7.3.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/third_party/example/android/gradle/wrapper/gradle-wrapper.properties b/third_party/example/android/gradle/wrapper/gradle-wrapper.properties index 939efa2951bf..6b665338b34e 100644 --- a/third_party/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/third_party/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip From 748001681bd73b58590a45cc2ef7155e29483927 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 13 Feb 2023 09:09:31 -0800 Subject: [PATCH 476/512] Hide vector_graphics_compiler types (#853) --- third_party/CHANGELOG.md | 4 ++ third_party/lib/src/loaders.dart | 106 ++++++++++++++++++++++++++++--- third_party/lib/svg.dart | 3 - 3 files changed, 100 insertions(+), 13 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 5578c9834802..a2e397f28ae3 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## Next + +- Fix internal Color representation leakage from `package:vector_graphics_compiler`. + ## 2.0.0+1 - Fix bug in asset loading from packages. diff --git a/third_party/lib/src/loaders.dart b/third_party/lib/src/loaders.dart index d7d456f7d2d2..48086f72ac9a 100644 --- a/third_party/lib/src/loaders.dart +++ b/third_party/lib/src/loaders.dart @@ -5,12 +5,93 @@ import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/src/utilities/http.dart'; import 'package:vector_graphics/vector_graphics.dart'; -import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; +import 'package:vector_graphics_compiler/vector_graphics_compiler.dart' as vg; import '../svg.dart' show svg; import 'utilities/compute.dart'; import 'utilities/file.dart'; +/// A theme used when decoding an SVG picture. +@immutable +class SvgTheme { + /// Instantiates an SVG theme with the [currentColor] + /// and [fontSize]. + /// + /// Defaults the [fontSize] to 14. + const SvgTheme({ + this.currentColor, + this.fontSize = 14, + double? xHeight, + }) : xHeight = xHeight ?? fontSize / 2; + + /// The default color applied to SVG elements that inherit the color property. + /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword + final Color? currentColor; + + /// The font size used when calculating em units of SVG elements. + /// See: https://www.w3.org/TR/SVG11/coords.html#Units + final double fontSize; + + /// The x-height (corpus size) of the font used when calculating ex units of SVG elements. + /// Defaults to [fontSize] / 2 if not provided. + /// See: https://www.w3.org/TR/SVG11/coords.html#Units, https://en.wikipedia.org/wiki/X-height + final double xHeight; + + vg.SvgTheme _toVgTheme() { + return vg.SvgTheme( + currentColor: currentColor != null ? vg.Color(currentColor!.value) : null, + fontSize: fontSize, + xHeight: xHeight, + ); + } + + @override + bool operator ==(dynamic other) { + if (other.runtimeType != runtimeType) { + return false; + } + + return other is SvgTheme && + currentColor == other.currentColor && + fontSize == other.fontSize && + xHeight == other.xHeight; + } + + @override + int get hashCode => Object.hash(currentColor, fontSize, xHeight); + + @override + String toString() => + 'SvgTheme(currentColor: $currentColor, fontSize: $fontSize, xHeight: $xHeight)'; +} + +/// A class that transforms from one color to another during SVG parsing. +abstract class ColorMapper { + /// Returns a new color to use in place of [color] during SVG parsing. + /// + /// The SVG parser will call this method every time it parses a color + Color substitute( + String? id, + String elementName, + String attributeName, + Color color, + ); +} + +class _DelegateVgColorMapper extends vg.ColorMapper { + _DelegateVgColorMapper(this.colorMapper); + + final ColorMapper colorMapper; + + @override + vg.Color substitute( + String? id, String elementName, String attributeName, vg.Color color) { + final Color substituteColor = colorMapper.substitute( + id, elementName, attributeName, Color(color.value)); + return vg.Color(substituteColor.value); + } +} + /// A [BytesLoader] that parses a SVG data in an isolate and creates a /// vector_graphics binary representation. abstract class SvgLoader extends BytesLoader { @@ -38,15 +119,20 @@ abstract class SvgLoader extends BytesLoader { Future _load(BuildContext? context) { return prepareMessage(context).then((T? message) { return compute((T? message) { - return encodeSvg( - xml: provideSvg(message), - theme: theme, - colorMapper: colorMapper, - debugName: 'Svg loader', - enableClippingOptimizer: false, - enableMaskingOptimizer: false, - enableOverdrawOptimizer: false, - ).buffer.asByteData(); + return vg + .encodeSvg( + xml: provideSvg(message), + theme: theme._toVgTheme(), + colorMapper: colorMapper == null + ? null + : _DelegateVgColorMapper(colorMapper!), + debugName: 'Svg loader', + enableClippingOptimizer: false, + enableMaskingOptimizer: false, + enableOverdrawOptimizer: false, + ) + .buffer + .asByteData(); }, message, debugLabel: 'Load Bytes'); }); } diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 3e2ca5c26810..63162a78c6de 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -3,7 +3,6 @@ import 'dart:ui' as ui; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:vector_graphics/vector_graphics_compat.dart'; -import 'package:vector_graphics_compiler/vector_graphics_compiler.dart'; import 'src/cache.dart'; import 'src/loaders.dart'; @@ -11,8 +10,6 @@ import 'src/utilities/file.dart'; export 'package:vector_graphics/vector_graphics.dart' show BytesLoader, vg, VectorGraphicUtilities, PictureInfo; -export 'package:vector_graphics_compiler/vector_graphics_compiler.dart' - show SvgTheme; export 'src/cache.dart'; export 'src/loaders.dart'; From 7f2b2bc8e23ae4d7ed0e62e0c94862b800aafc5e Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 13 Feb 2023 09:34:32 -0800 Subject: [PATCH 477/512] disable isolate parsing in debug mode (#854) Co-authored-by: Dan Field --- third_party/CHANGELOG.md | 1 + third_party/lib/src/utilities/_compute_io.dart | 8 -------- third_party/lib/src/utilities/_compute_none.dart | 2 -- third_party/lib/src/utilities/compute.dart | 11 +++++------ 4 files changed, 6 insertions(+), 16 deletions(-) delete mode 100644 third_party/lib/src/utilities/_compute_io.dart delete mode 100644 third_party/lib/src/utilities/_compute_none.dart diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index a2e397f28ae3..01e58d8897d9 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -2,6 +2,7 @@ ## Next +- Disable Isolate parsing in debug mode. - Fix internal Color representation leakage from `package:vector_graphics_compiler`. ## 2.0.0+1 diff --git a/third_party/lib/src/utilities/_compute_io.dart b/third_party/lib/src/utilities/_compute_io.dart deleted file mode 100644 index 22e4f2e25143..000000000000 --- a/third_party/lib/src/utilities/_compute_io.dart +++ /dev/null @@ -1,8 +0,0 @@ -import 'dart:io'; - -import 'package:flutter/foundation.dart'; - -/// Whether to use an isolate-spawning version of compute or not. -final bool isTest = - kDebugMode && Platform.executable.endsWith('flutter_tester') || - Platform.executable.endsWith('flutter_tester.exe'); diff --git a/third_party/lib/src/utilities/_compute_none.dart b/third_party/lib/src/utilities/_compute_none.dart deleted file mode 100644 index db635bb45017..000000000000 --- a/third_party/lib/src/utilities/_compute_none.dart +++ /dev/null @@ -1,2 +0,0 @@ -/// Whether to use an isolate-spawning version of compute or not. -const bool isTest = true; diff --git a/third_party/lib/src/utilities/compute.dart b/third_party/lib/src/utilities/compute.dart index 5a50b0eb481e..7b8eab69d0f6 100644 --- a/third_party/lib/src/utilities/compute.dart +++ b/third_party/lib/src/utilities/compute.dart @@ -2,8 +2,6 @@ import 'dart:async'; import 'package:flutter/foundation.dart' as foundation; -import '_compute_io.dart' if (dart.library.html) '_compute_none.dart'; - Future _testCompute( foundation.ComputeCallback callback, Q message, {String? debugLabel}) { @@ -14,11 +12,12 @@ Future _testCompute( final FutureOr result = callback(message); if (result is Future) { return result; - } else { - return foundation.SynchronousFuture(result); } + return foundation.SynchronousFuture(result); } /// A compute implementation that does not spawn isolates in tests. -final foundation.ComputeImpl compute = - isTest ? _testCompute : foundation.compute; +const foundation.ComputeImpl compute = + (foundation.kDebugMode || foundation.kIsWeb) + ? _testCompute + : foundation.compute; From c27cac9c251cee14c8675f0e9dfcd85dddd6fdb4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 13 Feb 2023 09:35:29 -0800 Subject: [PATCH 478/512] bumps for 2.0.1 --- third_party/CHANGELOG.md | 2 +- third_party/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 01e58d8897d9..a77d94340783 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGES -## Next +## 2.0.1 - Disable Isolate parsing in debug mode. - Fix internal Color representation leakage from `package:vector_graphics_compiler`. diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 845cd1356cd5..c8f8a75fea17 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.0+1 +version: 2.0.1 dependencies: flutter: From 0fb0be1f06cf561b331f8c7b3b74d491b1e5e57d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 21 Feb 2023 22:22:24 -0800 Subject: [PATCH 479/512] Consume new vector_graphics --- third_party/CHANGELOG.md | 5 +++++ third_party/lib/src/loaders.dart | 6 +++--- third_party/pubspec.yaml | 8 ++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index a77d94340783..1aec2547c5ff 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 2.0.2 + +- Consume newer version of vector_graphics with multiple fixes around + inheritence, patterns, and currentColor handling. + ## 2.0.1 - Disable Isolate parsing in debug mode. diff --git a/third_party/lib/src/loaders.dart b/third_party/lib/src/loaders.dart index 48086f72ac9a..ce42884f9b90 100644 --- a/third_party/lib/src/loaders.dart +++ b/third_party/lib/src/loaders.dart @@ -19,14 +19,14 @@ class SvgTheme { /// /// Defaults the [fontSize] to 14. const SvgTheme({ - this.currentColor, + this.currentColor = const Color(0xFF000000), this.fontSize = 14, double? xHeight, }) : xHeight = xHeight ?? fontSize / 2; /// The default color applied to SVG elements that inherit the color property. /// See: https://developer.mozilla.org/en-US/docs/Web/CSS/color_value#currentcolor_keyword - final Color? currentColor; + final Color currentColor; /// The font size used when calculating em units of SVG elements. /// See: https://www.w3.org/TR/SVG11/coords.html#Units @@ -39,7 +39,7 @@ class SvgTheme { vg.SvgTheme _toVgTheme() { return vg.SvgTheme( - currentColor: currentColor != null ? vg.Color(currentColor!.value) : null, + currentColor: vg.Color(currentColor.value), fontSize: fontSize, xHeight: xHeight, ); diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index c8f8a75fea17..834a3e19263d 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,14 +2,14 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.1 +version: 2.0.2 dependencies: flutter: sdk: flutter - vector_graphics: ^1.0.1 - vector_graphics_codec: ^1.0.1 - vector_graphics_compiler: ^1.0.1 + vector_graphics: ^1.1.0 + vector_graphics_codec: ^1.1.0 + vector_graphics_compiler: ^1.1.0 dev_dependencies: flutter_test: From c98bc778b78c731f09876fb32c3be8bbb6174b1b Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 9 Mar 2023 09:12:19 -0800 Subject: [PATCH 480/512] Fix faulty cache assertion, bump vg (#879) * Fix faulty cache assertion, bump vg * fixes --- third_party/CHANGELOG.md | 7 ++++++- third_party/lib/src/cache.dart | 3 +-- third_party/pubspec.yaml | 8 ++++---- third_party/test/cache_test.dart | 30 +++++++++++++++++++++++++++++- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 1aec2547c5ff..8fdb2654c6bc 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,8 +1,13 @@ # CHANGES +## 2.0.3 + +- Require newer version of vector_graphics. +- Fix bug in cache that incorrectly fired assert. + ## 2.0.2 -- Consume newer version of vector_graphics with multiple fixes around +- Require newer version of vector_graphics with multiple fixes around inheritence, patterns, and currentColor handling. ## 2.0.1 diff --git a/third_party/lib/src/cache.dart b/third_party/lib/src/cache.dart index 3eb9fba25359..3623a35cda58 100644 --- a/third_party/lib/src/cache.dart +++ b/third_party/lib/src/cache.dart @@ -87,7 +87,6 @@ class Cache { pendingResult.then((ByteData data) { _pending.remove(key); _add(key, data); - result = data; // in case it was a synchronous future. }); } @@ -101,7 +100,7 @@ class Cache { void _add(Object key, ByteData result) { if (maximumSize > 0) { - assert(_cache.length < maximumSize); + assert(_cache.containsKey(key) || _cache.length < maximumSize); _cache[key] = result; } assert(_cache.length <= maximumSize); diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 834a3e19263d..124330e8b82b 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,14 +2,14 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.2 +version: 2.0.3 dependencies: flutter: sdk: flutter - vector_graphics: ^1.1.0 - vector_graphics_codec: ^1.1.0 - vector_graphics_compiler: ^1.1.0 + vector_graphics: ^1.1.3 + vector_graphics_codec: ^1.1.3 + vector_graphics_compiler: ^1.1.3 dev_dependencies: flutter_test: diff --git a/third_party/test/cache_test.dart b/third_party/test/cache_test.dart index a45f642f8808..b1f5801e958f 100644 --- a/third_party/test/cache_test.dart +++ b/third_party/test/cache_test.dart @@ -1,6 +1,6 @@ import 'dart:async'; -import 'dart:typed_data'; +import 'package:flutter/foundation.dart'; import 'package:flutter_svg/src/cache.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -77,4 +77,32 @@ void main() { expect(cache.evict(2), false); expect(cache.evict(3), true); }); + + test('Adding beyond max with synchronous futures', () async { + final Cache cache = Cache(); + cache.maximumSize = 2; + final Future completerA = + SynchronousFuture(ByteData(1)); + final Future completerB = + SynchronousFuture(ByteData(2)); + final Future completerC = + SynchronousFuture(ByteData(3)); + + expect(cache.count, 0); + + cache.putIfAbsent(1, () => completerA); + expect(cache.count, 1); + + cache.putIfAbsent(2, () => completerB); + expect(cache.count, 2); + + cache.putIfAbsent(2, () => completerB); + expect(cache.count, 2); + + cache.putIfAbsent(3, () => completerC); + expect(cache.count, 2); + + cache.putIfAbsent(2, () => completerB); + expect(cache.count, 2); + }); } From e9819c64787e815adbccc0fe282f5a31d8395c37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20Kl=C3=B6ckner?= Date: Mon, 13 Mar 2023 17:18:38 +0100 Subject: [PATCH 481/512] Reintroduce clip behavior (#860) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Reintroduce clipBehavior See https://github.com/dnfield/vector_graphics/pull/180 * Use vector_graphics PR, revert before merge * Update pubspec.yaml --------- Co-authored-by: Fabian Klöckner Co-authored-by: Dan Field --- third_party/lib/svg.dart | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/third_party/lib/svg.dart b/third_party/lib/svg.dart index 63162a78c6de..ae2d221d6e1e 100644 --- a/third_party/lib/svg.dart +++ b/third_party/lib/svg.dart @@ -83,8 +83,8 @@ class SvgPicture extends StatelessWidget { this.colorFilter, this.semanticsLabel, this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, this.theme = const SvgTheme(), - @deprecated Clip? clipBehavior, @deprecated bool cacheColorFilter = false, }) : super(key: key); @@ -178,11 +178,11 @@ class SvgPicture extends StatelessWidget { this.placeholderBuilder, this.semanticsLabel, this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, this.theme = const SvgTheme(), ui.ColorFilter? colorFilter, @deprecated ui.Color? color, @deprecated ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, - @deprecated Clip? clipBehavior, @deprecated bool cacheColorFilter = false, }) : bytesLoader = SvgAssetLoader( assetName, @@ -241,7 +241,7 @@ class SvgPicture extends StatelessWidget { @deprecated ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, this.semanticsLabel, this.excludeFromSemantics = false, - @deprecated Clip? clipBehavior, + this.clipBehavior = Clip.hardEdge, @deprecated bool cacheColorFilter = false, this.theme = const SvgTheme(), }) : bytesLoader = SvgNetworkLoader(url, headers: headers, theme: theme), @@ -293,8 +293,8 @@ class SvgPicture extends StatelessWidget { @deprecated ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, this.semanticsLabel, this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, this.theme = const SvgTheme(), - @deprecated Clip? clipBehavior, @deprecated bool cacheColorFilter = false, }) : bytesLoader = SvgFileLoader(file, theme: theme), colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode), @@ -342,8 +342,8 @@ class SvgPicture extends StatelessWidget { @deprecated ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, this.semanticsLabel, this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, this.theme = const SvgTheme(), - @deprecated Clip? clipBehavior, @deprecated bool cacheColorFilter = false, }) : bytesLoader = SvgBytesLoader(bytes, theme: theme), colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode), @@ -391,8 +391,8 @@ class SvgPicture extends StatelessWidget { @deprecated ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, this.semanticsLabel, this.excludeFromSemantics = false, + this.clipBehavior = Clip.hardEdge, this.theme = const SvgTheme(), - @deprecated Clip? clipBehavior, @deprecated bool cacheColorFilter = false, }) : bytesLoader = SvgStringLoader(string, theme: theme), colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode), @@ -468,6 +468,14 @@ class SvgPicture extends StatelessWidget { /// application. final bool excludeFromSemantics; + /// The content will be clipped (or not) according to this option. + /// + /// See the enum [Clip] for details of all possible options and their common + /// use cases. + /// + /// Defaults to [Clip.hardEdge], and must not be null. + final Clip clipBehavior; + /// The color filter, if any, to apply to this widget. final ColorFilter? colorFilter; @@ -484,6 +492,7 @@ class SvgPicture extends StatelessWidget { alignment: alignment, semanticsLabel: semanticsLabel, excludeFromSemantics: excludeFromSemantics, + clipBehavior: clipBehavior, colorFilter: colorFilter, placeholderBuilder: placeholderBuilder, clipViewbox: !allowDrawingOutsideViewBox, From a8e36a2252bef6fdf12a7ccd74c0c15df9578f07 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 14 Mar 2023 14:32:34 -0700 Subject: [PATCH 482/512] Manage cache count correctly (#885) * Manage cache count correctly * Fix breakage --- third_party/lib/src/cache.dart | 10 ++++++---- third_party/test/cache_test.dart | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/third_party/lib/src/cache.dart b/third_party/lib/src/cache.dart index 3623a35cda58..adfd9bb23f22 100644 --- a/third_party/lib/src/cache.dart +++ b/third_party/lib/src/cache.dart @@ -79,9 +79,6 @@ class Cache { // and thus move it to the end of the list. _cache.remove(key); } else { - if (_cache.length == maximumSize && maximumSize > 0) { - _cache.remove(_cache.keys.first); - } pendingResult = loader(); _pending[key] = pendingResult; pendingResult.then((ByteData data) { @@ -100,7 +97,12 @@ class Cache { void _add(Object key, ByteData result) { if (maximumSize > 0) { - assert(_cache.containsKey(key) || _cache.length < maximumSize); + if (_cache.containsKey(key)) { + _cache.remove(key); // update LRU. + } else if (_cache.length == maximumSize && maximumSize > 0) { + _cache.remove(_cache.keys.first); + } + assert(_cache.length < maximumSize); _cache[key] = result; } assert(_cache.length <= maximumSize); diff --git a/third_party/test/cache_test.dart b/third_party/test/cache_test.dart index b1f5801e958f..1a049107c8b5 100644 --- a/third_party/test/cache_test.dart +++ b/third_party/test/cache_test.dart @@ -105,4 +105,32 @@ void main() { cache.putIfAbsent(2, () => completerB); expect(cache.count, 2); }); + + test('Futures completing late/together', () async { + final Cache cache = Cache(); + cache.maximumSize = 2; + final Completer completerA = Completer(); + final Completer completerB = Completer(); + final Completer completerC = Completer(); + + expect(cache.count, 0); + + cache.putIfAbsent(1, () => completerA.future); + cache.putIfAbsent(2, () => completerB.future); + completerA.complete(ByteData(1)); + completerB.complete(ByteData(1)); + + expect(cache.count, 0); + await null; + expect(cache.count, 2); + + cache.putIfAbsent(3, () => completerC.future); + expect(cache.count, 2); + + completerC.complete(ByteData(1)); + expect(cache.count, 2); + + await null; + expect(cache.count, 2); + }); } From 246f5e4547c2b2affa19708876e36321bb238bd6 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 14 Mar 2023 14:34:13 -0700 Subject: [PATCH 483/512] bumps --- third_party/CHANGELOG.md | 6 ++++++ third_party/pubspec.yaml | 8 ++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 8fdb2654c6bc..971b04c35a67 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGES +## 2.0.4 + +- Newer version of vector_graphics. +- Caching bug fix. +- Reintroduce clipBehavior. + ## 2.0.3 - Require newer version of vector_graphics. diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 124330e8b82b..48e40bb3d733 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,14 +2,14 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.3 +version: 2.0.4 dependencies: flutter: sdk: flutter - vector_graphics: ^1.1.3 - vector_graphics_codec: ^1.1.3 - vector_graphics_compiler: ^1.1.3 + vector_graphics: ^1.1.4 + vector_graphics_codec: ^1.1.4 + vector_graphics_compiler: ^1.1.4 dev_dependencies: flutter_test: From a1a16a3d4dbd541777b79a100baa79b21f9aef0a Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 14 Mar 2023 15:07:56 -0700 Subject: [PATCH 484/512] Remove unecessary file --- third_party/lib/src/utilities/errors.dart | 22 ---------------------- 1 file changed, 22 deletions(-) delete mode 100644 third_party/lib/src/utilities/errors.dart diff --git a/third_party/lib/src/utilities/errors.dart b/third_party/lib/src/utilities/errors.dart deleted file mode 100644 index e16c76e823a7..000000000000 --- a/third_party/lib/src/utilities/errors.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:flutter/foundation.dart'; - -/// Reports a missing or undefined `` element. -void reportMissingDef(String? key, String? href, String methodName) { - FlutterError.onError!( - FlutterErrorDetails( - exception: FlutterError.fromParts([ - ErrorSummary('Failed to find definition for $href'), - ErrorDescription( - 'This library only supports and xlink:href references that ' - 'are defined ahead of their references.'), - ErrorHint( - 'This error can be caused when the desired definition is defined after the element ' - 'referring to it (e.g. at the end of the file), or defined in another file.'), - ErrorDescription( - 'This error is treated as non-fatal, but your SVG file will likely not render as intended'), - ]), - context: ErrorDescription('while parsing $key in $methodName'), - library: 'SVG', - ), - ); -} From 685758f430a0711e920cfe3aa0ce85a0d520ddb4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 16 Mar 2023 09:54:06 -0700 Subject: [PATCH 485/512] Allow malformed UTF-8 (#889) --- third_party/lib/src/loaders.dart | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/third_party/lib/src/loaders.dart b/third_party/lib/src/loaders.dart index ce42884f9b90..cab86f75fed1 100644 --- a/third_party/lib/src/loaders.dart +++ b/third_party/lib/src/loaders.dart @@ -37,7 +37,8 @@ class SvgTheme { /// See: https://www.w3.org/TR/SVG11/coords.html#Units, https://en.wikipedia.org/wiki/X-height final double xHeight; - vg.SvgTheme _toVgTheme() { + /// Creates a [vg.SvgTheme] from this. + vg.SvgTheme toVgTheme() { return vg.SvgTheme( currentColor: vg.Color(currentColor.value), fontSize: fontSize, @@ -122,7 +123,7 @@ abstract class SvgLoader extends BytesLoader { return vg .encodeSvg( xml: provideSvg(message), - theme: theme._toVgTheme(), + theme: theme.toVgTheme(), colorMapper: colorMapper == null ? null : _DelegateVgColorMapper(colorMapper!), @@ -189,7 +190,7 @@ class SvgBytesLoader extends SvgLoader { final Uint8List bytes; @override - String provideSvg(void message) => utf8.decode(bytes); + String provideSvg(void message) => utf8.decode(bytes, allowMalformed: true); @override int get hashCode => Object.hash(svg, theme, colorMapper); @@ -219,7 +220,7 @@ class SvgFileLoader extends SvgLoader { @override String provideSvg(void message) { final Uint8List bytes = file.readAsBytesSync(); - return utf8.decode(bytes); + return utf8.decode(bytes, allowMalformed: true); } @override @@ -306,7 +307,7 @@ class SvgAssetLoader extends SvgLoader { @override String provideSvg(ByteData? message) => - utf8.decode(message!.buffer.asUint8List()); + utf8.decode(message!.buffer.asUint8List(), allowMalformed: true); @override Object cacheKey(BuildContext? context) { @@ -358,7 +359,8 @@ class SvgNetworkLoader extends SvgLoader { } @override - String provideSvg(Uint8List? message) => utf8.decode(message!); + String provideSvg(Uint8List? message) => + utf8.decode(message!, allowMalformed: true); @override int get hashCode => Object.hash(url, headers, theme, colorMapper); From 82eaa81ce249ee59735f0f1b4a81737efffef3d5 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 16 Mar 2023 10:57:01 -0700 Subject: [PATCH 486/512] Make cache respect SvgTheme (#890) --- third_party/lib/src/loaders.dart | 52 +++++++++++++++++++++++++++--- third_party/test/loaders_test.dart | 17 ++++++++++ 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/third_party/lib/src/loaders.dart b/third_party/lib/src/loaders.dart index cab86f75fed1..13356a27cc78 100644 --- a/third_party/lib/src/loaders.dart +++ b/third_party/lib/src/loaders.dart @@ -18,6 +18,12 @@ class SvgTheme { /// and [fontSize]. /// /// Defaults the [fontSize] to 14. + // WARNING WARNING WARNING + // If this codebase ever decides to default the font size to something off the + // BuildContext, caching logic will have to be updated. The font size can + // temporarily and unexpectedly change during route transitions in common + // patterns used in `MaterialApp`. This busts caching and destroys + // performance. const SvgTheme({ this.currentColor = const Color(0xFF000000), this.fontSize = 14, @@ -144,6 +150,39 @@ abstract class SvgLoader extends BytesLoader { Future loadBytes(BuildContext? context) { return svg.cache.putIfAbsent(cacheKey(context), () => _load(context)); } + + @override + SvgCacheKey cacheKey(BuildContext? context) { + return SvgCacheKey(keyData: this, theme: theme); + } +} + +/// A [SvgTheme] aware cache key. +/// +/// The theme must be part of the cache key to ensure that otherwise similar +/// SVGs get cached separately. +@immutable +class SvgCacheKey { + /// See [SvgCacheKey]. + const SvgCacheKey({required this.theme, required this.keyData}); + + /// The theme for this cached SVG. + final SvgTheme theme; + + /// The other key data for the SVG. + /// + /// For most loaders, using the loader object itself is suitable. + final Object keyData; + + @override + int get hashCode => Object.hash(theme, keyData); + + @override + bool operator ==(Object other) { + return other is SvgCacheKey && + other.theme == theme && + other.keyData == keyData; + } } /// A [BytesLoader] that parses an SVG string in an isolate and creates a @@ -310,11 +349,14 @@ class SvgAssetLoader extends SvgLoader { utf8.decode(message!.buffer.asUint8List(), allowMalformed: true); @override - Object cacheKey(BuildContext? context) { - return _AssetByteLoaderCacheKey( - assetName, - packageName, - _resolveBundle(context), + SvgCacheKey cacheKey(BuildContext? context) { + return SvgCacheKey( + theme: theme, + keyData: _AssetByteLoaderCacheKey( + assetName, + packageName, + _resolveBundle(context), + ), ); } diff --git a/third_party/test/loaders_test.dart b/third_party/test/loaders_test.dart index 46fafe1e0650..9f11d051741a 100644 --- a/third_party/test/loaders_test.dart +++ b/third_party/test/loaders_test.dart @@ -3,11 +3,28 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { + setUp(() { + svg.cache.clear(); + svg.cache.maximumSize = 100; + }); + + test('SvgTheme updates the cache', () async { + const TestLoader loaderA = + TestLoader(theme: SvgTheme(currentColor: Color(0xFFABCDEF))); + const TestLoader loaderB = + TestLoader(theme: SvgTheme(currentColor: Color(0xFFFEDCBA))); + final ByteData bytesA = await loaderA.loadBytes(null); + final ByteData bytesB = await loaderB.loadBytes(null); + expect(identical(bytesA, bytesB), false); + expect(svg.cache.count, 2); + }); + test('Uses the cache', () async { const TestLoader loader = TestLoader(); final ByteData bytes = await loader.loadBytes(null); final ByteData bytes2 = await loader.loadBytes(null); expect(identical(bytes, bytes2), true); + expect(svg.cache.count, 1); }); test('Empty cache', () async { From bab2ce02e7b9df33142d32023ff36d89b762b36e Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 7 Apr 2023 20:49:14 -0700 Subject: [PATCH 487/512] Consider colorMapper for cache key data (#902) * Consider colorMapper for cache key data * format --- third_party/lib/src/loaders.dart | 24 ++++++++++++++++++++---- third_party/test/loaders_test.dart | 30 +++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/third_party/lib/src/loaders.dart b/third_party/lib/src/loaders.dart index 13356a27cc78..5ebd8dd66641 100644 --- a/third_party/lib/src/loaders.dart +++ b/third_party/lib/src/loaders.dart @@ -73,7 +73,14 @@ class SvgTheme { } /// A class that transforms from one color to another during SVG parsing. +/// +/// This object must be immutable so that it is suitable for use in the +/// [svg.cache]. +@immutable abstract class ColorMapper { + /// Allows const constructors on subclasses. + const ColorMapper(); + /// Returns a new color to use in place of [color] during SVG parsing. /// /// The SVG parser will call this method every time it parses a color @@ -153,7 +160,7 @@ abstract class SvgLoader extends BytesLoader { @override SvgCacheKey cacheKey(BuildContext? context) { - return SvgCacheKey(keyData: this, theme: theme); + return SvgCacheKey(keyData: this, theme: theme, colorMapper: colorMapper); } } @@ -164,7 +171,11 @@ abstract class SvgLoader extends BytesLoader { @immutable class SvgCacheKey { /// See [SvgCacheKey]. - const SvgCacheKey({required this.theme, required this.keyData}); + const SvgCacheKey({ + required this.theme, + required this.keyData, + required this.colorMapper, + }); /// The theme for this cached SVG. final SvgTheme theme; @@ -174,14 +185,18 @@ class SvgCacheKey { /// For most loaders, using the loader object itself is suitable. final Object keyData; + /// The color mapper for the SVG, if any. + final ColorMapper? colorMapper; + @override - int get hashCode => Object.hash(theme, keyData); + int get hashCode => Object.hash(theme, keyData, colorMapper); @override bool operator ==(Object other) { return other is SvgCacheKey && other.theme == theme && - other.keyData == keyData; + other.keyData == keyData && + other.colorMapper == colorMapper; } } @@ -352,6 +367,7 @@ class SvgAssetLoader extends SvgLoader { SvgCacheKey cacheKey(BuildContext? context) { return SvgCacheKey( theme: theme, + colorMapper: colorMapper, keyData: _AssetByteLoaderCacheKey( assetName, packageName, diff --git a/third_party/test/loaders_test.dart b/third_party/test/loaders_test.dart index 9f11d051741a..591b3b01e708 100644 --- a/third_party/test/loaders_test.dart +++ b/third_party/test/loaders_test.dart @@ -1,4 +1,5 @@ import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -8,6 +9,15 @@ void main() { svg.cache.maximumSize = 100; }); + test('ColorMapper updates the cache', () async { + const TestLoader loaderA = TestLoader(); + const TestLoader loaderB = TestLoader(colorMapper: _TestColorMapper()); + final ByteData bytesA = await loaderA.loadBytes(null); + final ByteData bytesB = await loaderB.loadBytes(null); + expect(identical(bytesA, bytesB), false); + expect(svg.cache.count, 2); + }); + test('SvgTheme updates the cache', () async { const TestLoader loaderA = TestLoader(theme: SvgTheme(currentColor: Color(0xFFABCDEF))); @@ -61,10 +71,28 @@ class TestBundle extends Fake implements AssetBundle { } class TestLoader extends SvgLoader { - const TestLoader({super.theme, super.colorMapper}); + const TestLoader({this.keyName = 'A', super.theme, super.colorMapper}); + + final String keyName; @override String provideSvg(void message) { return ''; } + + @override + SvgCacheKey cacheKey(BuildContext? context) { + return SvgCacheKey( + theme: theme, colorMapper: colorMapper, keyData: keyName); + } +} + +class _TestColorMapper extends ColorMapper { + const _TestColorMapper(); + + @override + Color substitute( + String? id, String elementName, String attributeName, Color color) { + return color; + } } From bbeaf77ff896609365a8fa97eb348bb12d5124cd Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 10 Apr 2023 09:42:51 -0700 Subject: [PATCH 488/512] Bumps for 2.0.5 --- third_party/CHANGELOG.md | 5 +++++ third_party/pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/third_party/CHANGELOG.md b/third_party/CHANGELOG.md index 971b04c35a67..d0f7a7225e21 100644 --- a/third_party/CHANGELOG.md +++ b/third_party/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 2.0.5 + +- Allow malformed UTF-8 in loaders. +- Make the cache respect the SvgTheme and ColorMapper, if present. + ## 2.0.4 - Newer version of vector_graphics. diff --git a/third_party/pubspec.yaml b/third_party/pubspec.yaml index 48e40bb3d733..6801822a168e 100644 --- a/third_party/pubspec.yaml +++ b/third_party/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.4 +version: 2.0.5 dependencies: flutter: From 2a4b2ce68ab8ed81e4637319e718d1f7873b8baa Mon Sep 17 00:00:00 2001 From: SimonWeidemann <79831243+SimonWeidemann@users.noreply.github.com> Date: Tue, 11 Apr 2023 18:16:18 +0200 Subject: [PATCH 489/512] Add svg finder (#880) * Extract flutter svg to package * Add flutter svg test library * Adjust readme * Update and rename ci.yml to flutter_svg.yml * Create flutter_svg_test.yml --------- Co-authored-by: Dan Field --- .../{ => packages/flutter_svg}/CHANGELOG.md | 0 third_party/packages/flutter_svg/README.md | 147 ++++++++++++++ .../flutter_svg}/example/.gitignore | 0 .../flutter_svg}/example/.metadata | 0 .../flutter_svg}/example/README.md | 0 .../example/analysis_options.yaml | 0 .../flutter_svg}/example/android/.gitignore | 0 .../example/android/app/build.gradle | 0 .../android/app/src/debug/AndroidManifest.xml | 0 .../android/app/src/main/AndroidManifest.xml | 0 .../com/example/example/MainActivity.kt | 0 .../res/drawable-v21/launch_background.xml | 0 .../main/res/drawable/launch_background.xml | 0 .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin .../app/src/main/res/values-night/styles.xml | 0 .../app/src/main/res/values/styles.xml | 0 .../app/src/profile/AndroidManifest.xml | 0 .../flutter_svg}/example/android/build.gradle | 0 .../example/android/example_android.iml | 0 .../example/android/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.properties | 0 .../example/android/settings.gradle | 0 .../assets/android_vd/battery_charging.xml | 0 .../flutter_svg}/example/assets/dart.svg | 0 .../deborah_ufw/new-action-expander.svg | 0 .../example/assets/deborah_ufw/new-camera.svg | 0 .../assets/deborah_ufw/new-gif-button.svg | 0 .../example/assets/deborah_ufw/new-gif.svg | 0 .../example/assets/deborah_ufw/new-image.svg | 0 .../assets/deborah_ufw/new-mention.svg | 0 .../assets/deborah_ufw/new-pause-button.svg | 0 .../assets/deborah_ufw/new-play-button.svg | 0 .../assets/deborah_ufw/new-send-circle.svg | 0 .../example/assets/deborah_ufw/numeric_25.svg | 0 .../example/assets/flutter_logo.svg | 0 .../assets/noto-emoji/emoji_u1f600.svg | 0 .../example/assets/simple/blend_and_mask.svg | 0 .../assets/simple/blend_mode_devil.svg | 0 .../example/assets/simple/clip_path.svg | 0 .../example/assets/simple/clip_path_2.svg | 0 .../example/assets/simple/clip_path_3.svg | 0 .../assets/simple/clip_path_transform.svg | 0 .../example/assets/simple/dash_path.svg | 0 .../example/assets/simple/dash_zero.svg | 0 .../example/assets/simple/ellipse.svg | 0 .../example/assets/simple/empty_defs.svg | 0 .../example/assets/simple/empty_group.svg | 0 .../example/assets/simple/equation.svg | 0 .../assets/simple/fill-rule-inherit.svg | 0 .../assets/simple/fill_inheritence_test.svg | 0 .../assets/simple/group_composite_opacity.svg | 0 .../assets/simple/group_fill_opacity.svg | 0 .../example/assets/simple/group_in_defs.svg | 0 .../example/assets/simple/group_mask.svg | 0 .../example/assets/simple/group_opacity.svg | 0 .../assets/simple/group_opacity_transform.svg | 0 .../example/assets/simple/hidden.svg | 0 .../example/assets/simple/href-fill.svg | 0 .../example/assets/simple/image.svg | 0 .../example/assets/simple/image_def.svg | 0 .../image_transform_before_translate.svg | 0 .../simple/implicit_fill_with_opacity.svg | 0 .../assets/simple/invalid_dash_array.svg | 0 .../example/assets/simple/linear_gradient.svg | 0 .../assets/simple/linear_gradient_2.svg | 0 ...gradient_absolute_user_space_translate.svg | 0 ...gradient_percentage_bounding_translate.svg | 0 ...adient_percentage_user_space_translate.svg | 0 .../assets/simple/linear_gradient_xlink.svg | 0 .../example/assets/simple/male.svg | 0 .../example/assets/simple/mask.svg | 0 .../assets/simple/mask_with_gradient.svg | 0 .../example/assets/simple/mask_with_use.svg | 0 .../example/assets/simple/mask_with_use2.svg | 0 .../example/assets/simple/nested_group.svg | 0 .../example/assets/simple/opacity_on_path.svg | 0 .../example/assets/simple/radial_gradient.svg | 0 ...gradient_absolute_user_space_translate.svg | 0 .../assets/simple/radial_gradient_focal.svg | 0 ...gradient_percentage_bounding_translate.svg | 0 ...adient_percentage_user_space_translate.svg | 0 .../assets/simple/radial_gradient_xlink.svg | 0 .../simple/radial_ref_linear_gradient.svg | 0 .../example/assets/simple/rect_rrect.svg | 0 .../assets/simple/rect_rrect_no_ry.svg | 0 .../assets/simple/stroke_inherit_circles.svg | 0 .../example/assets/simple/style_attr.svg | 0 .../example/assets/simple/text.svg | 0 .../example/assets/simple/text_2.svg | 0 .../example/assets/simple/text_3.svg | 0 .../example/assets/simple/text_4.svg | 0 .../example/assets/simple/text_5.svg | 0 .../example/assets/simple/text_6.svg | 0 .../example/assets/simple/use_circles.svg | 0 .../example/assets/simple/use_circles_def.svg | 0 .../example/assets/simple/use_emc2.svg | 0 .../example/assets/simple/use_fill.svg | 0 .../example/assets/simple/use_fill_test.svg | 0 .../assets/simple/use_opacity_grid.svg | 0 .../assets/simple/width_height_viewbox.svg | 0 .../assets/simple/zero_width_strokes.svg | 0 .../example/assets/svg_currentcolor.svg | 0 .../example/assets/text_transform.svg | 0 .../example/assets/w3samples/aa.svg | 0 .../example/assets/w3samples/alphachannel.svg | 0 .../assets/wikimedia/Firefox_Logo_2017.svg | 0 .../wikimedia/Flag_of_the_United_States.svg | 0 .../assets/wikimedia/Ghostscript_Tiger.svg | 0 .../example/assets/wikimedia/chess_knight.svg | 0 .../flutter_svg}/example/example.iml | 0 .../flutter_svg}/example/example_android.iml | 0 .../flutter_svg}/example/ios/.gitignore | 0 .../ios/Flutter/AppFrameworkInfo.plist | 0 .../example/ios/Flutter/Debug.xcconfig | 0 .../example/ios/Flutter/Release.xcconfig | 0 .../ios/Runner.xcodeproj/project.pbxproj | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/WorkspaceSettings.xcsettings | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/WorkspaceSettings.xcsettings | 0 .../example/ios/Runner/AppDelegate.h | 0 .../example/ios/Runner/AppDelegate.m | 0 .../example/ios/Runner/AppDelegate.swift | 0 .../AppIcon.appiconset/Contents.json | 0 .../Icon-App-1024x1024@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin .../Icon-App-83.5x83.5@2x.png | Bin .../LaunchImage.imageset/Contents.json | 0 .../LaunchImage.imageset/LaunchImage.png | Bin .../LaunchImage.imageset/LaunchImage@2x.png | Bin .../LaunchImage.imageset/LaunchImage@3x.png | Bin .../LaunchImage.imageset/README.md | 0 .../Runner/Base.lproj/LaunchScreen.storyboard | 0 .../ios/Runner/Base.lproj/Main.storyboard | 0 .../example/ios/Runner/Info.plist | 0 .../ios/Runner/Runner-Bridging-Header.h | 0 .../flutter_svg}/example/ios/Runner/main.m | 0 .../flutter_svg}/example/lib/main.dart | 0 .../flutter_svg}/example/lib/simple.dart | 0 .../flutter_svg}/example/linux/.gitignore | 0 .../flutter_svg}/example/linux/CMakeLists.txt | 0 .../example/linux/flutter/CMakeLists.txt | 0 .../flutter/generated_plugin_registrant.cc | 0 .../flutter/generated_plugin_registrant.h | 0 .../linux/flutter/generated_plugins.cmake | 0 .../flutter_svg}/example/linux/main.cc | 0 .../example/linux/my_application.cc | 0 .../example/linux/my_application.h | 0 .../flutter_svg}/example/macos/.gitignore | 0 .../macos/Flutter/Flutter-Debug.xcconfig | 0 .../macos/Flutter/Flutter-Release.xcconfig | 0 .../Flutter/GeneratedPluginRegistrant.swift | 0 .../macos/Runner.xcodeproj/project.pbxproj | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../xcshareddata/xcschemes/Runner.xcscheme | 0 .../contents.xcworkspacedata | 0 .../xcshareddata/IDEWorkspaceChecks.plist | 0 .../example/macos/Runner/AppDelegate.swift | 0 .../AppIcon.appiconset/Contents.json | 0 .../AppIcon.appiconset/app_icon_1024.png | Bin .../AppIcon.appiconset/app_icon_128.png | Bin .../AppIcon.appiconset/app_icon_16.png | Bin .../AppIcon.appiconset/app_icon_256.png | Bin .../AppIcon.appiconset/app_icon_32.png | Bin .../AppIcon.appiconset/app_icon_512.png | Bin .../AppIcon.appiconset/app_icon_64.png | Bin .../macos/Runner/Base.lproj/MainMenu.xib | 0 .../macos/Runner/Configs/AppInfo.xcconfig | 0 .../macos/Runner/Configs/Debug.xcconfig | 0 .../macos/Runner/Configs/Release.xcconfig | 0 .../macos/Runner/Configs/Warnings.xcconfig | 0 .../macos/Runner/DebugProfile.entitlements | 0 .../example/macos/Runner/Info.plist | 0 .../macos/Runner/MainFlutterWindow.swift | 0 .../example/macos/Runner/Release.entitlements | 0 .../flutter_svg}/example/pubspec.yaml | 0 .../example/test_driver/bench.dart | 0 .../example/test_driver/bench_test.dart | 0 .../example/test_driver/repaint.dart | 0 .../example/test_driver/repaint_test.dart | 0 .../flutter_svg}/example/web/favicon.png | Bin .../example/web/icons/Icon-192.png | Bin .../example/web/icons/Icon-512.png | Bin .../example/web/icons/Icon-maskable-192.png | Bin .../example/web/icons/Icon-maskable-512.png | Bin .../flutter_svg}/example/web/index.html | 0 .../flutter_svg}/example/web/manifest.json | 0 .../flutter_svg}/example/windows/.gitignore | 0 .../example/windows/CMakeLists.txt | 0 .../example/windows/flutter/CMakeLists.txt | 0 .../flutter/generated_plugin_registrant.cc | 0 .../flutter/generated_plugin_registrant.h | 0 .../windows/flutter/generated_plugins.cmake | 0 .../example/windows/runner/CMakeLists.txt | 0 .../example/windows/runner/Runner.rc | 0 .../example/windows/runner/flutter_window.cpp | 0 .../example/windows/runner/flutter_window.h | 0 .../example/windows/runner/main.cpp | 0 .../example/windows/runner/resource.h | 0 .../windows/runner/resources/app_icon.ico | Bin .../example/windows/runner/run_loop.cpp | 0 .../example/windows/runner/run_loop.h | 0 .../windows/runner/runner.exe.manifest | 0 .../example/windows/runner/utils.cpp | 0 .../example/windows/runner/utils.h | 0 .../example/windows/runner/win32_window.cpp | 0 .../example/windows/runner/win32_window.h | 0 .../flutter_svg}/flutter_svg.iml | 0 .../flutter_svg}/flutter_svg_android.iml | 0 .../flutter_svg}/lib/flutter_svg.dart | 0 .../flutter_svg}/lib/src/cache.dart | 0 .../flutter_svg}/lib/src/loaders.dart | 0 .../lib/src/utilities/_file_io.dart | 0 .../lib/src/utilities/_file_none.dart | 0 .../lib/src/utilities/_http_io.dart | 0 .../lib/src/utilities/_http_web.dart | 0 .../lib/src/utilities/compute.dart | 0 .../flutter_svg}/lib/src/utilities/file.dart | 0 .../flutter_svg}/lib/src/utilities/http.dart | 0 .../lib/src/utilities/numbers.dart | 0 .../{ => packages/flutter_svg}/lib/svg.dart | 0 .../{ => packages/flutter_svg}/pubspec.yaml | 2 +- .../flutter_svg}/test/cache_test.dart | 0 .../text_color_filter_isolatedDiff.png | Bin 0 -> 2247 bytes .../failures/text_color_filter_maskedDiff.png | Bin 0 -> 2421 bytes .../text_color_filter_masterImage.png} | Bin .../failures/text_color_filter_testImage.png | Bin 0 -> 2429 bytes .../test/golden_widget/circle.em_ex.png | Bin .../test/golden_widget/circle.em_ex2.png | Bin .../test/golden_widget/columns_and_rows.png | Bin .../test/golden_widget/ellipse.em_ex.png | Bin .../test/golden_widget/ellipse.em_ex2.png | Bin .../test/golden_widget/flutter_logo.asset.png | Bin .../golden_widget/flutter_logo.memory.png | Bin .../golden_widget/flutter_logo.natural.png | Bin .../golden_widget/flutter_logo.network.png | Bin ...go.string.color_filter.blendmode_color.png | Bin .../flutter_logo.string.color_filter.png | Bin .../golden_widget/flutter_logo.string.ltr.png | Bin .../golden_widget/flutter_logo.string.png | Bin .../golden_widget/flutter_logo.string.rtl.png | Bin .../test/golden_widget/line.em_ex.png | Bin .../test/golden_widget/line.em_ex2.png | Bin .../test/golden_widget/rect.em_ex.png | Bin .../test/golden_widget/rect.em_ex2.png | Bin .../stick_figure.withclipping.png | Bin .../test/golden_widget/text_color_filter.png | Bin 0 -> 2396 bytes .../test/golden_widget/two_of_same.png | Bin .../flutter_svg}/test/loaders_test.dart | 0 .../test/no_width_height_test.dart | 0 .../flutter_svg}/test/widget_svg_test.dart | 0 .../packages/flutter_svg_test/README.md | 44 +++++ .../lib/flutter_svg_test.dart | 170 ++++++++++++++++ .../packages/flutter_svg_test/pubspec.yaml | 18 ++ .../flutter_svg_test/test/flutter_logo.svg | 20 ++ .../test/flutter_svg_test_test.dart | 183 ++++++++++++++++++ 275 files changed, 583 insertions(+), 1 deletion(-) rename third_party/{ => packages/flutter_svg}/CHANGELOG.md (100%) create mode 100644 third_party/packages/flutter_svg/README.md rename third_party/{ => packages/flutter_svg}/example/.gitignore (100%) rename third_party/{ => packages/flutter_svg}/example/.metadata (100%) rename third_party/{ => packages/flutter_svg}/example/README.md (100%) rename third_party/{ => packages/flutter_svg}/example/analysis_options.yaml (100%) rename third_party/{ => packages/flutter_svg}/example/android/.gitignore (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/build.gradle (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/debug/AndroidManifest.xml (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/AndroidManifest.xml (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/res/drawable-v21/launch_background.xml (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/res/drawable/launch_background.xml (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/res/values-night/styles.xml (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/main/res/values/styles.xml (100%) rename third_party/{ => packages/flutter_svg}/example/android/app/src/profile/AndroidManifest.xml (100%) rename third_party/{ => packages/flutter_svg}/example/android/build.gradle (100%) rename third_party/{ => packages/flutter_svg}/example/android/example_android.iml (100%) rename third_party/{ => packages/flutter_svg}/example/android/gradle.properties (100%) rename third_party/{ => packages/flutter_svg}/example/android/gradle/wrapper/gradle-wrapper.properties (100%) rename third_party/{ => packages/flutter_svg}/example/android/settings.gradle (100%) rename third_party/{ => packages/flutter_svg}/example/assets/android_vd/battery_charging.xml (100%) rename third_party/{ => packages/flutter_svg}/example/assets/dart.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/deborah_ufw/new-action-expander.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/deborah_ufw/new-camera.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/deborah_ufw/new-gif-button.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/deborah_ufw/new-gif.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/deborah_ufw/new-image.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/deborah_ufw/new-mention.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/deborah_ufw/new-pause-button.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/deborah_ufw/new-play-button.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/deborah_ufw/new-send-circle.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/deborah_ufw/numeric_25.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/flutter_logo.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/noto-emoji/emoji_u1f600.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/blend_and_mask.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/blend_mode_devil.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/clip_path.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/clip_path_2.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/clip_path_3.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/clip_path_transform.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/dash_path.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/dash_zero.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/ellipse.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/empty_defs.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/empty_group.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/equation.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/fill-rule-inherit.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/fill_inheritence_test.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/group_composite_opacity.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/group_fill_opacity.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/group_in_defs.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/group_mask.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/group_opacity.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/group_opacity_transform.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/hidden.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/href-fill.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/image.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/image_def.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/image_transform_before_translate.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/implicit_fill_with_opacity.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/invalid_dash_array.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/linear_gradient.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/linear_gradient_2.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/linear_gradient_absolute_user_space_translate.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/linear_gradient_percentage_bounding_translate.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/linear_gradient_percentage_user_space_translate.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/linear_gradient_xlink.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/male.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/mask.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/mask_with_gradient.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/mask_with_use.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/mask_with_use2.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/nested_group.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/opacity_on_path.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/radial_gradient.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/radial_gradient_absolute_user_space_translate.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/radial_gradient_focal.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/radial_gradient_percentage_bounding_translate.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/radial_gradient_percentage_user_space_translate.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/radial_gradient_xlink.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/radial_ref_linear_gradient.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/rect_rrect.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/rect_rrect_no_ry.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/stroke_inherit_circles.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/style_attr.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/text.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/text_2.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/text_3.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/text_4.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/text_5.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/text_6.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/use_circles.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/use_circles_def.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/use_emc2.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/use_fill.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/use_fill_test.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/use_opacity_grid.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/width_height_viewbox.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/simple/zero_width_strokes.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/svg_currentcolor.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/text_transform.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/w3samples/aa.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/w3samples/alphachannel.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/wikimedia/Firefox_Logo_2017.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/wikimedia/Flag_of_the_United_States.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/wikimedia/Ghostscript_Tiger.svg (100%) rename third_party/{ => packages/flutter_svg}/example/assets/wikimedia/chess_knight.svg (100%) rename third_party/{ => packages/flutter_svg}/example/example.iml (100%) rename third_party/{ => packages/flutter_svg}/example/example_android.iml (100%) rename third_party/{ => packages/flutter_svg}/example/ios/.gitignore (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Flutter/AppFrameworkInfo.plist (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Flutter/Debug.xcconfig (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Flutter/Release.xcconfig (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner.xcodeproj/project.pbxproj (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner.xcworkspace/contents.xcworkspacedata (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/AppDelegate.h (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/AppDelegate.m (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/AppDelegate.swift (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Base.lproj/LaunchScreen.storyboard (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Base.lproj/Main.storyboard (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Info.plist (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/Runner-Bridging-Header.h (100%) rename third_party/{ => packages/flutter_svg}/example/ios/Runner/main.m (100%) rename third_party/{ => packages/flutter_svg}/example/lib/main.dart (100%) rename third_party/{ => packages/flutter_svg}/example/lib/simple.dart (100%) rename third_party/{ => packages/flutter_svg}/example/linux/.gitignore (100%) rename third_party/{ => packages/flutter_svg}/example/linux/CMakeLists.txt (100%) rename third_party/{ => packages/flutter_svg}/example/linux/flutter/CMakeLists.txt (100%) rename third_party/{ => packages/flutter_svg}/example/linux/flutter/generated_plugin_registrant.cc (100%) rename third_party/{ => packages/flutter_svg}/example/linux/flutter/generated_plugin_registrant.h (100%) rename third_party/{ => packages/flutter_svg}/example/linux/flutter/generated_plugins.cmake (100%) rename third_party/{ => packages/flutter_svg}/example/linux/main.cc (100%) rename third_party/{ => packages/flutter_svg}/example/linux/my_application.cc (100%) rename third_party/{ => packages/flutter_svg}/example/linux/my_application.h (100%) rename third_party/{ => packages/flutter_svg}/example/macos/.gitignore (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Flutter/Flutter-Debug.xcconfig (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Flutter/Flutter-Release.xcconfig (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Flutter/GeneratedPluginRegistrant.swift (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner.xcodeproj/project.pbxproj (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner.xcworkspace/contents.xcworkspacedata (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/AppDelegate.swift (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Base.lproj/MainMenu.xib (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Configs/AppInfo.xcconfig (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Configs/Debug.xcconfig (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Configs/Release.xcconfig (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Configs/Warnings.xcconfig (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/DebugProfile.entitlements (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Info.plist (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/MainFlutterWindow.swift (100%) rename third_party/{ => packages/flutter_svg}/example/macos/Runner/Release.entitlements (100%) rename third_party/{ => packages/flutter_svg}/example/pubspec.yaml (100%) rename third_party/{ => packages/flutter_svg}/example/test_driver/bench.dart (100%) rename third_party/{ => packages/flutter_svg}/example/test_driver/bench_test.dart (100%) rename third_party/{ => packages/flutter_svg}/example/test_driver/repaint.dart (100%) rename third_party/{ => packages/flutter_svg}/example/test_driver/repaint_test.dart (100%) rename third_party/{ => packages/flutter_svg}/example/web/favicon.png (100%) rename third_party/{ => packages/flutter_svg}/example/web/icons/Icon-192.png (100%) rename third_party/{ => packages/flutter_svg}/example/web/icons/Icon-512.png (100%) rename third_party/{ => packages/flutter_svg}/example/web/icons/Icon-maskable-192.png (100%) rename third_party/{ => packages/flutter_svg}/example/web/icons/Icon-maskable-512.png (100%) rename third_party/{ => packages/flutter_svg}/example/web/index.html (100%) rename third_party/{ => packages/flutter_svg}/example/web/manifest.json (100%) rename third_party/{ => packages/flutter_svg}/example/windows/.gitignore (100%) rename third_party/{ => packages/flutter_svg}/example/windows/CMakeLists.txt (100%) rename third_party/{ => packages/flutter_svg}/example/windows/flutter/CMakeLists.txt (100%) rename third_party/{ => packages/flutter_svg}/example/windows/flutter/generated_plugin_registrant.cc (100%) rename third_party/{ => packages/flutter_svg}/example/windows/flutter/generated_plugin_registrant.h (100%) rename third_party/{ => packages/flutter_svg}/example/windows/flutter/generated_plugins.cmake (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/CMakeLists.txt (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/Runner.rc (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/flutter_window.cpp (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/flutter_window.h (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/main.cpp (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/resource.h (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/resources/app_icon.ico (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/run_loop.cpp (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/run_loop.h (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/runner.exe.manifest (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/utils.cpp (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/utils.h (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/win32_window.cpp (100%) rename third_party/{ => packages/flutter_svg}/example/windows/runner/win32_window.h (100%) rename third_party/{ => packages/flutter_svg}/flutter_svg.iml (100%) rename third_party/{ => packages/flutter_svg}/flutter_svg_android.iml (100%) rename third_party/{ => packages/flutter_svg}/lib/flutter_svg.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/src/cache.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/src/loaders.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/src/utilities/_file_io.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/src/utilities/_file_none.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/src/utilities/_http_io.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/src/utilities/_http_web.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/src/utilities/compute.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/src/utilities/file.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/src/utilities/http.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/src/utilities/numbers.dart (100%) rename third_party/{ => packages/flutter_svg}/lib/svg.dart (100%) rename third_party/{ => packages/flutter_svg}/pubspec.yaml (90%) rename third_party/{ => packages/flutter_svg}/test/cache_test.dart (100%) create mode 100644 third_party/packages/flutter_svg/test/failures/text_color_filter_isolatedDiff.png create mode 100644 third_party/packages/flutter_svg/test/failures/text_color_filter_maskedDiff.png rename third_party/{test/golden_widget/text_color_filter.png => packages/flutter_svg/test/failures/text_color_filter_masterImage.png} (100%) create mode 100644 third_party/packages/flutter_svg/test/failures/text_color_filter_testImage.png rename third_party/{ => packages/flutter_svg}/test/golden_widget/circle.em_ex.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/circle.em_ex2.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/columns_and_rows.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/ellipse.em_ex.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/ellipse.em_ex2.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/flutter_logo.asset.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/flutter_logo.memory.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/flutter_logo.natural.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/flutter_logo.network.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/flutter_logo.string.color_filter.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/flutter_logo.string.ltr.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/flutter_logo.string.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/flutter_logo.string.rtl.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/line.em_ex.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/line.em_ex2.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/rect.em_ex.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/rect.em_ex2.png (100%) rename third_party/{ => packages/flutter_svg}/test/golden_widget/stick_figure.withclipping.png (100%) create mode 100644 third_party/packages/flutter_svg/test/golden_widget/text_color_filter.png rename third_party/{ => packages/flutter_svg}/test/golden_widget/two_of_same.png (100%) rename third_party/{ => packages/flutter_svg}/test/loaders_test.dart (100%) rename third_party/{ => packages/flutter_svg}/test/no_width_height_test.dart (100%) rename third_party/{ => packages/flutter_svg}/test/widget_svg_test.dart (100%) create mode 100644 third_party/packages/flutter_svg_test/README.md create mode 100644 third_party/packages/flutter_svg_test/lib/flutter_svg_test.dart create mode 100644 third_party/packages/flutter_svg_test/pubspec.yaml create mode 100644 third_party/packages/flutter_svg_test/test/flutter_logo.svg create mode 100644 third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart diff --git a/third_party/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md similarity index 100% rename from third_party/CHANGELOG.md rename to third_party/packages/flutter_svg/CHANGELOG.md diff --git a/third_party/packages/flutter_svg/README.md b/third_party/packages/flutter_svg/README.md new file mode 100644 index 000000000000..9ac9beb906f2 --- /dev/null +++ b/third_party/packages/flutter_svg/README.md @@ -0,0 +1,147 @@ +# flutter_svg + +[![Pub](https://img.shields.io/pub/v/flutter_svg.svg)](https://pub.dartlang.org/packages/flutter_svg) [![Coverage Status](https://coveralls.io/repos/github/dnfield/flutter_svg/badge.svg?branch=master)](https://coveralls.io/github/dnfield/flutter_svg?branch=master) + + +Flutter Logo which can be rendered by this package! + + +Draw SVG files using Flutter. + +## Getting Started + +Basic usage (to create an SVG rendering widget from an asset): + +```dart +final String assetName = 'assets/image.svg'; +final Widget svg = SvgPicture.asset( + assetName, + semanticsLabel: 'Acme Logo' +); +``` + +You can color/tint the image like so: + +```dart +final String assetName = 'assets/up_arrow.svg'; +final Widget svgIcon = SvgPicture.asset( + assetName, + colorFilter: ColorFilter.mode(Colors.red, BlendMode.srcIn), + semanticsLabel: 'A red up arrow' +); +``` + +The default placeholder is an empty box (`LimitedBox`) - although if a `height` +or `width` is specified on the `SvgPicture`, a `SizedBox` will be used instead +(which ensures better layout experience). There is currently no way to show an +Error visually, however errors will get properly logged to the console in debug +mode. + +You can also specify a placeholder widget. The placeholder will display during +parsing/loading (normally only relevant for network access). + +```dart +// Will print error messages to the console. +final String assetName = 'assets/image_that_does_not_exist.svg'; +final Widget svg = SvgPicture.asset( + assetName, +); + +final Widget networkSvg = SvgPicture.network( + 'https://site-that-takes-a-while.com/image.svg', + semanticsLabel: 'A shark?!', + placeholderBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator()), +); +``` + +If you'd like to render the SVG to some other canvas, you can do something like: + +```dart +import 'package:flutter_svg/flutter_svg.dart'; +final String rawSvg = '''...'''; +final PictureInfo pictureInfo = await vg.loadPicture(SvgStringLoader(rawSvg), null); + +// You can draw the picture to a canvas: +canvas.drawPicture(pictureInfo.picture); + +// Or convert the picture to a an image: +final ui.Image image = pictureInfo.picture.toImage(...); + +pictureInfo.picture.dispose(); +``` + +The `SvgPicture` helps to automate this logic, and it provides some convenience +wrappers for getting assets from multiple sources. Unlike the `vector_graphics` +package, this package _does not render the data to an `Image` at any point_. +This carries a performance penalty for some common use cases, but also allows +for more flexibility around scaling. + +See [main.dart](/../master/example/lib/main.dart) for a complete sample. + +## Precompiling and Optimizing SVGs + +The vector_graphics backend supports SVG compilation which produces a binary +format that is faster to parse and can optimize SVGs to reduce the amount of +clipping, masking, and overdraw. The SVG compilation is provided by +[`package:vector_graphics_compiler`](https://pub.dev/packages/vector_graphics_compiler). + +```sh +dart run vector_graphics_compiler -i assets/foo.svg -o assets/foo.svg.vec +``` + +The output `foo.svg.vec` can be loaded using the default constructor of +`SvgPicture`. + +```dart +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:vector_graphics/vector_graphics.dart'; + +final Widget svg = SvgPicture( + const AssetBytesLoader('assets/foo.svg.vec') +); +``` + +### Check SVG compatibility + +An SVG can be tested for compatibility with the vector graphics backend by +running the compiler locally to see if any errors are thrown. + +```sh +dart run vector_graphics_compiler -i $SVG_FILE -o $TEMPORARY_OUTPUT_TO_BE_DELETED --no-optimize-masks --no-optimize-clips --no-optimize-overdraw --no-tessellate +``` + +## Recommended Adobe Illustrator SVG Configuration +- In Styling: choose Presentation Attributes instead of Inline CSS because CSS is not fully supported. +- In Images: choose Embded not Linked to other file to get a single svg with no dependency to other files. +- In Objects IDs: choose layer names to add every layer name to svg tags or you can use minimal,it is optional. +![Export configuration](https://user-images.githubusercontent.com/2842459/62599914-91de9c00-b8fe-11e9-8fb7-4af57d5100f7.png) + +## SVG sample attribution + +SVGs in `/assets/w3samples` pulled from [W3 sample files](https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/) + +SVGs in `/assets/deborah_ufw` provided by @deborah-ufw + +SVGs in `/assets/simple` are pulled from trivial examples or generated to test +basic functionality - some of them come directly from the SVG 1.1 spec. Some +have also come or been adapted from issues raised in this repository. + +SVGs in `/assets/wikimedia` are pulled from [Wikimedia Commons](https://commons.wikimedia.org/wiki/Main_Page) + +Android Drawables in `/assets/android_vd` are pulled from Android Documentation +and examples. + +The Flutter Logo created based on the Flutter Logo Widget © Google. + +The Dart logo is from +[dartlang.org](https://github.com/dart-lang/site-shared/blob/master/src/_assets/images/dart/logo%2Btext/horizontal/original.svg) +© Google + +SVGs in `/assets/noto-emoji` are from [Google i18n noto-emoji](https://github.com/googlei18n/noto-emoji), +licensed under the Apache license. + +Please submit SVGs that can't render properly (e.g. that don't render here the +way they do in chrome), as long as they're not using anything "probably out of +scope" (above). diff --git a/third_party/example/.gitignore b/third_party/packages/flutter_svg/example/.gitignore similarity index 100% rename from third_party/example/.gitignore rename to third_party/packages/flutter_svg/example/.gitignore diff --git a/third_party/example/.metadata b/third_party/packages/flutter_svg/example/.metadata similarity index 100% rename from third_party/example/.metadata rename to third_party/packages/flutter_svg/example/.metadata diff --git a/third_party/example/README.md b/third_party/packages/flutter_svg/example/README.md similarity index 100% rename from third_party/example/README.md rename to third_party/packages/flutter_svg/example/README.md diff --git a/third_party/example/analysis_options.yaml b/third_party/packages/flutter_svg/example/analysis_options.yaml similarity index 100% rename from third_party/example/analysis_options.yaml rename to third_party/packages/flutter_svg/example/analysis_options.yaml diff --git a/third_party/example/android/.gitignore b/third_party/packages/flutter_svg/example/android/.gitignore similarity index 100% rename from third_party/example/android/.gitignore rename to third_party/packages/flutter_svg/example/android/.gitignore diff --git a/third_party/example/android/app/build.gradle b/third_party/packages/flutter_svg/example/android/app/build.gradle similarity index 100% rename from third_party/example/android/app/build.gradle rename to third_party/packages/flutter_svg/example/android/app/build.gradle diff --git a/third_party/example/android/app/src/debug/AndroidManifest.xml b/third_party/packages/flutter_svg/example/android/app/src/debug/AndroidManifest.xml similarity index 100% rename from third_party/example/android/app/src/debug/AndroidManifest.xml rename to third_party/packages/flutter_svg/example/android/app/src/debug/AndroidManifest.xml diff --git a/third_party/example/android/app/src/main/AndroidManifest.xml b/third_party/packages/flutter_svg/example/android/app/src/main/AndroidManifest.xml similarity index 100% rename from third_party/example/android/app/src/main/AndroidManifest.xml rename to third_party/packages/flutter_svg/example/android/app/src/main/AndroidManifest.xml diff --git a/third_party/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/third_party/packages/flutter_svg/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt similarity index 100% rename from third_party/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt rename to third_party/packages/flutter_svg/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt diff --git a/third_party/example/android/app/src/main/res/drawable-v21/launch_background.xml b/third_party/packages/flutter_svg/example/android/app/src/main/res/drawable-v21/launch_background.xml similarity index 100% rename from third_party/example/android/app/src/main/res/drawable-v21/launch_background.xml rename to third_party/packages/flutter_svg/example/android/app/src/main/res/drawable-v21/launch_background.xml diff --git a/third_party/example/android/app/src/main/res/drawable/launch_background.xml b/third_party/packages/flutter_svg/example/android/app/src/main/res/drawable/launch_background.xml similarity index 100% rename from third_party/example/android/app/src/main/res/drawable/launch_background.xml rename to third_party/packages/flutter_svg/example/android/app/src/main/res/drawable/launch_background.xml diff --git a/third_party/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png similarity index 100% rename from third_party/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png rename to third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/third_party/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png similarity index 100% rename from third_party/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png rename to third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/third_party/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png similarity index 100% rename from third_party/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png rename to third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/third_party/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png similarity index 100% rename from third_party/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png rename to third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/third_party/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png similarity index 100% rename from third_party/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png rename to third_party/packages/flutter_svg/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/third_party/example/android/app/src/main/res/values-night/styles.xml b/third_party/packages/flutter_svg/example/android/app/src/main/res/values-night/styles.xml similarity index 100% rename from third_party/example/android/app/src/main/res/values-night/styles.xml rename to third_party/packages/flutter_svg/example/android/app/src/main/res/values-night/styles.xml diff --git a/third_party/example/android/app/src/main/res/values/styles.xml b/third_party/packages/flutter_svg/example/android/app/src/main/res/values/styles.xml similarity index 100% rename from third_party/example/android/app/src/main/res/values/styles.xml rename to third_party/packages/flutter_svg/example/android/app/src/main/res/values/styles.xml diff --git a/third_party/example/android/app/src/profile/AndroidManifest.xml b/third_party/packages/flutter_svg/example/android/app/src/profile/AndroidManifest.xml similarity index 100% rename from third_party/example/android/app/src/profile/AndroidManifest.xml rename to third_party/packages/flutter_svg/example/android/app/src/profile/AndroidManifest.xml diff --git a/third_party/example/android/build.gradle b/third_party/packages/flutter_svg/example/android/build.gradle similarity index 100% rename from third_party/example/android/build.gradle rename to third_party/packages/flutter_svg/example/android/build.gradle diff --git a/third_party/example/android/example_android.iml b/third_party/packages/flutter_svg/example/android/example_android.iml similarity index 100% rename from third_party/example/android/example_android.iml rename to third_party/packages/flutter_svg/example/android/example_android.iml diff --git a/third_party/example/android/gradle.properties b/third_party/packages/flutter_svg/example/android/gradle.properties similarity index 100% rename from third_party/example/android/gradle.properties rename to third_party/packages/flutter_svg/example/android/gradle.properties diff --git a/third_party/example/android/gradle/wrapper/gradle-wrapper.properties b/third_party/packages/flutter_svg/example/android/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from third_party/example/android/gradle/wrapper/gradle-wrapper.properties rename to third_party/packages/flutter_svg/example/android/gradle/wrapper/gradle-wrapper.properties diff --git a/third_party/example/android/settings.gradle b/third_party/packages/flutter_svg/example/android/settings.gradle similarity index 100% rename from third_party/example/android/settings.gradle rename to third_party/packages/flutter_svg/example/android/settings.gradle diff --git a/third_party/example/assets/android_vd/battery_charging.xml b/third_party/packages/flutter_svg/example/assets/android_vd/battery_charging.xml similarity index 100% rename from third_party/example/assets/android_vd/battery_charging.xml rename to third_party/packages/flutter_svg/example/assets/android_vd/battery_charging.xml diff --git a/third_party/example/assets/dart.svg b/third_party/packages/flutter_svg/example/assets/dart.svg similarity index 100% rename from third_party/example/assets/dart.svg rename to third_party/packages/flutter_svg/example/assets/dart.svg diff --git a/third_party/example/assets/deborah_ufw/new-action-expander.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-action-expander.svg similarity index 100% rename from third_party/example/assets/deborah_ufw/new-action-expander.svg rename to third_party/packages/flutter_svg/example/assets/deborah_ufw/new-action-expander.svg diff --git a/third_party/example/assets/deborah_ufw/new-camera.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-camera.svg similarity index 100% rename from third_party/example/assets/deborah_ufw/new-camera.svg rename to third_party/packages/flutter_svg/example/assets/deborah_ufw/new-camera.svg diff --git a/third_party/example/assets/deborah_ufw/new-gif-button.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-gif-button.svg similarity index 100% rename from third_party/example/assets/deborah_ufw/new-gif-button.svg rename to third_party/packages/flutter_svg/example/assets/deborah_ufw/new-gif-button.svg diff --git a/third_party/example/assets/deborah_ufw/new-gif.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-gif.svg similarity index 100% rename from third_party/example/assets/deborah_ufw/new-gif.svg rename to third_party/packages/flutter_svg/example/assets/deborah_ufw/new-gif.svg diff --git a/third_party/example/assets/deborah_ufw/new-image.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-image.svg similarity index 100% rename from third_party/example/assets/deborah_ufw/new-image.svg rename to third_party/packages/flutter_svg/example/assets/deborah_ufw/new-image.svg diff --git a/third_party/example/assets/deborah_ufw/new-mention.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-mention.svg similarity index 100% rename from third_party/example/assets/deborah_ufw/new-mention.svg rename to third_party/packages/flutter_svg/example/assets/deborah_ufw/new-mention.svg diff --git a/third_party/example/assets/deborah_ufw/new-pause-button.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-pause-button.svg similarity index 100% rename from third_party/example/assets/deborah_ufw/new-pause-button.svg rename to third_party/packages/flutter_svg/example/assets/deborah_ufw/new-pause-button.svg diff --git a/third_party/example/assets/deborah_ufw/new-play-button.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-play-button.svg similarity index 100% rename from third_party/example/assets/deborah_ufw/new-play-button.svg rename to third_party/packages/flutter_svg/example/assets/deborah_ufw/new-play-button.svg diff --git a/third_party/example/assets/deborah_ufw/new-send-circle.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/new-send-circle.svg similarity index 100% rename from third_party/example/assets/deborah_ufw/new-send-circle.svg rename to third_party/packages/flutter_svg/example/assets/deborah_ufw/new-send-circle.svg diff --git a/third_party/example/assets/deborah_ufw/numeric_25.svg b/third_party/packages/flutter_svg/example/assets/deborah_ufw/numeric_25.svg similarity index 100% rename from third_party/example/assets/deborah_ufw/numeric_25.svg rename to third_party/packages/flutter_svg/example/assets/deborah_ufw/numeric_25.svg diff --git a/third_party/example/assets/flutter_logo.svg b/third_party/packages/flutter_svg/example/assets/flutter_logo.svg similarity index 100% rename from third_party/example/assets/flutter_logo.svg rename to third_party/packages/flutter_svg/example/assets/flutter_logo.svg diff --git a/third_party/example/assets/noto-emoji/emoji_u1f600.svg b/third_party/packages/flutter_svg/example/assets/noto-emoji/emoji_u1f600.svg similarity index 100% rename from third_party/example/assets/noto-emoji/emoji_u1f600.svg rename to third_party/packages/flutter_svg/example/assets/noto-emoji/emoji_u1f600.svg diff --git a/third_party/example/assets/simple/blend_and_mask.svg b/third_party/packages/flutter_svg/example/assets/simple/blend_and_mask.svg similarity index 100% rename from third_party/example/assets/simple/blend_and_mask.svg rename to third_party/packages/flutter_svg/example/assets/simple/blend_and_mask.svg diff --git a/third_party/example/assets/simple/blend_mode_devil.svg b/third_party/packages/flutter_svg/example/assets/simple/blend_mode_devil.svg similarity index 100% rename from third_party/example/assets/simple/blend_mode_devil.svg rename to third_party/packages/flutter_svg/example/assets/simple/blend_mode_devil.svg diff --git a/third_party/example/assets/simple/clip_path.svg b/third_party/packages/flutter_svg/example/assets/simple/clip_path.svg similarity index 100% rename from third_party/example/assets/simple/clip_path.svg rename to third_party/packages/flutter_svg/example/assets/simple/clip_path.svg diff --git a/third_party/example/assets/simple/clip_path_2.svg b/third_party/packages/flutter_svg/example/assets/simple/clip_path_2.svg similarity index 100% rename from third_party/example/assets/simple/clip_path_2.svg rename to third_party/packages/flutter_svg/example/assets/simple/clip_path_2.svg diff --git a/third_party/example/assets/simple/clip_path_3.svg b/third_party/packages/flutter_svg/example/assets/simple/clip_path_3.svg similarity index 100% rename from third_party/example/assets/simple/clip_path_3.svg rename to third_party/packages/flutter_svg/example/assets/simple/clip_path_3.svg diff --git a/third_party/example/assets/simple/clip_path_transform.svg b/third_party/packages/flutter_svg/example/assets/simple/clip_path_transform.svg similarity index 100% rename from third_party/example/assets/simple/clip_path_transform.svg rename to third_party/packages/flutter_svg/example/assets/simple/clip_path_transform.svg diff --git a/third_party/example/assets/simple/dash_path.svg b/third_party/packages/flutter_svg/example/assets/simple/dash_path.svg similarity index 100% rename from third_party/example/assets/simple/dash_path.svg rename to third_party/packages/flutter_svg/example/assets/simple/dash_path.svg diff --git a/third_party/example/assets/simple/dash_zero.svg b/third_party/packages/flutter_svg/example/assets/simple/dash_zero.svg similarity index 100% rename from third_party/example/assets/simple/dash_zero.svg rename to third_party/packages/flutter_svg/example/assets/simple/dash_zero.svg diff --git a/third_party/example/assets/simple/ellipse.svg b/third_party/packages/flutter_svg/example/assets/simple/ellipse.svg similarity index 100% rename from third_party/example/assets/simple/ellipse.svg rename to third_party/packages/flutter_svg/example/assets/simple/ellipse.svg diff --git a/third_party/example/assets/simple/empty_defs.svg b/third_party/packages/flutter_svg/example/assets/simple/empty_defs.svg similarity index 100% rename from third_party/example/assets/simple/empty_defs.svg rename to third_party/packages/flutter_svg/example/assets/simple/empty_defs.svg diff --git a/third_party/example/assets/simple/empty_group.svg b/third_party/packages/flutter_svg/example/assets/simple/empty_group.svg similarity index 100% rename from third_party/example/assets/simple/empty_group.svg rename to third_party/packages/flutter_svg/example/assets/simple/empty_group.svg diff --git a/third_party/example/assets/simple/equation.svg b/third_party/packages/flutter_svg/example/assets/simple/equation.svg similarity index 100% rename from third_party/example/assets/simple/equation.svg rename to third_party/packages/flutter_svg/example/assets/simple/equation.svg diff --git a/third_party/example/assets/simple/fill-rule-inherit.svg b/third_party/packages/flutter_svg/example/assets/simple/fill-rule-inherit.svg similarity index 100% rename from third_party/example/assets/simple/fill-rule-inherit.svg rename to third_party/packages/flutter_svg/example/assets/simple/fill-rule-inherit.svg diff --git a/third_party/example/assets/simple/fill_inheritence_test.svg b/third_party/packages/flutter_svg/example/assets/simple/fill_inheritence_test.svg similarity index 100% rename from third_party/example/assets/simple/fill_inheritence_test.svg rename to third_party/packages/flutter_svg/example/assets/simple/fill_inheritence_test.svg diff --git a/third_party/example/assets/simple/group_composite_opacity.svg b/third_party/packages/flutter_svg/example/assets/simple/group_composite_opacity.svg similarity index 100% rename from third_party/example/assets/simple/group_composite_opacity.svg rename to third_party/packages/flutter_svg/example/assets/simple/group_composite_opacity.svg diff --git a/third_party/example/assets/simple/group_fill_opacity.svg b/third_party/packages/flutter_svg/example/assets/simple/group_fill_opacity.svg similarity index 100% rename from third_party/example/assets/simple/group_fill_opacity.svg rename to third_party/packages/flutter_svg/example/assets/simple/group_fill_opacity.svg diff --git a/third_party/example/assets/simple/group_in_defs.svg b/third_party/packages/flutter_svg/example/assets/simple/group_in_defs.svg similarity index 100% rename from third_party/example/assets/simple/group_in_defs.svg rename to third_party/packages/flutter_svg/example/assets/simple/group_in_defs.svg diff --git a/third_party/example/assets/simple/group_mask.svg b/third_party/packages/flutter_svg/example/assets/simple/group_mask.svg similarity index 100% rename from third_party/example/assets/simple/group_mask.svg rename to third_party/packages/flutter_svg/example/assets/simple/group_mask.svg diff --git a/third_party/example/assets/simple/group_opacity.svg b/third_party/packages/flutter_svg/example/assets/simple/group_opacity.svg similarity index 100% rename from third_party/example/assets/simple/group_opacity.svg rename to third_party/packages/flutter_svg/example/assets/simple/group_opacity.svg diff --git a/third_party/example/assets/simple/group_opacity_transform.svg b/third_party/packages/flutter_svg/example/assets/simple/group_opacity_transform.svg similarity index 100% rename from third_party/example/assets/simple/group_opacity_transform.svg rename to third_party/packages/flutter_svg/example/assets/simple/group_opacity_transform.svg diff --git a/third_party/example/assets/simple/hidden.svg b/third_party/packages/flutter_svg/example/assets/simple/hidden.svg similarity index 100% rename from third_party/example/assets/simple/hidden.svg rename to third_party/packages/flutter_svg/example/assets/simple/hidden.svg diff --git a/third_party/example/assets/simple/href-fill.svg b/third_party/packages/flutter_svg/example/assets/simple/href-fill.svg similarity index 100% rename from third_party/example/assets/simple/href-fill.svg rename to third_party/packages/flutter_svg/example/assets/simple/href-fill.svg diff --git a/third_party/example/assets/simple/image.svg b/third_party/packages/flutter_svg/example/assets/simple/image.svg similarity index 100% rename from third_party/example/assets/simple/image.svg rename to third_party/packages/flutter_svg/example/assets/simple/image.svg diff --git a/third_party/example/assets/simple/image_def.svg b/third_party/packages/flutter_svg/example/assets/simple/image_def.svg similarity index 100% rename from third_party/example/assets/simple/image_def.svg rename to third_party/packages/flutter_svg/example/assets/simple/image_def.svg diff --git a/third_party/example/assets/simple/image_transform_before_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/image_transform_before_translate.svg similarity index 100% rename from third_party/example/assets/simple/image_transform_before_translate.svg rename to third_party/packages/flutter_svg/example/assets/simple/image_transform_before_translate.svg diff --git a/third_party/example/assets/simple/implicit_fill_with_opacity.svg b/third_party/packages/flutter_svg/example/assets/simple/implicit_fill_with_opacity.svg similarity index 100% rename from third_party/example/assets/simple/implicit_fill_with_opacity.svg rename to third_party/packages/flutter_svg/example/assets/simple/implicit_fill_with_opacity.svg diff --git a/third_party/example/assets/simple/invalid_dash_array.svg b/third_party/packages/flutter_svg/example/assets/simple/invalid_dash_array.svg similarity index 100% rename from third_party/example/assets/simple/invalid_dash_array.svg rename to third_party/packages/flutter_svg/example/assets/simple/invalid_dash_array.svg diff --git a/third_party/example/assets/simple/linear_gradient.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient.svg similarity index 100% rename from third_party/example/assets/simple/linear_gradient.svg rename to third_party/packages/flutter_svg/example/assets/simple/linear_gradient.svg diff --git a/third_party/example/assets/simple/linear_gradient_2.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_2.svg similarity index 100% rename from third_party/example/assets/simple/linear_gradient_2.svg rename to third_party/packages/flutter_svg/example/assets/simple/linear_gradient_2.svg diff --git a/third_party/example/assets/simple/linear_gradient_absolute_user_space_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_absolute_user_space_translate.svg similarity index 100% rename from third_party/example/assets/simple/linear_gradient_absolute_user_space_translate.svg rename to third_party/packages/flutter_svg/example/assets/simple/linear_gradient_absolute_user_space_translate.svg diff --git a/third_party/example/assets/simple/linear_gradient_percentage_bounding_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_percentage_bounding_translate.svg similarity index 100% rename from third_party/example/assets/simple/linear_gradient_percentage_bounding_translate.svg rename to third_party/packages/flutter_svg/example/assets/simple/linear_gradient_percentage_bounding_translate.svg diff --git a/third_party/example/assets/simple/linear_gradient_percentage_user_space_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_percentage_user_space_translate.svg similarity index 100% rename from third_party/example/assets/simple/linear_gradient_percentage_user_space_translate.svg rename to third_party/packages/flutter_svg/example/assets/simple/linear_gradient_percentage_user_space_translate.svg diff --git a/third_party/example/assets/simple/linear_gradient_xlink.svg b/third_party/packages/flutter_svg/example/assets/simple/linear_gradient_xlink.svg similarity index 100% rename from third_party/example/assets/simple/linear_gradient_xlink.svg rename to third_party/packages/flutter_svg/example/assets/simple/linear_gradient_xlink.svg diff --git a/third_party/example/assets/simple/male.svg b/third_party/packages/flutter_svg/example/assets/simple/male.svg similarity index 100% rename from third_party/example/assets/simple/male.svg rename to third_party/packages/flutter_svg/example/assets/simple/male.svg diff --git a/third_party/example/assets/simple/mask.svg b/third_party/packages/flutter_svg/example/assets/simple/mask.svg similarity index 100% rename from third_party/example/assets/simple/mask.svg rename to third_party/packages/flutter_svg/example/assets/simple/mask.svg diff --git a/third_party/example/assets/simple/mask_with_gradient.svg b/third_party/packages/flutter_svg/example/assets/simple/mask_with_gradient.svg similarity index 100% rename from third_party/example/assets/simple/mask_with_gradient.svg rename to third_party/packages/flutter_svg/example/assets/simple/mask_with_gradient.svg diff --git a/third_party/example/assets/simple/mask_with_use.svg b/third_party/packages/flutter_svg/example/assets/simple/mask_with_use.svg similarity index 100% rename from third_party/example/assets/simple/mask_with_use.svg rename to third_party/packages/flutter_svg/example/assets/simple/mask_with_use.svg diff --git a/third_party/example/assets/simple/mask_with_use2.svg b/third_party/packages/flutter_svg/example/assets/simple/mask_with_use2.svg similarity index 100% rename from third_party/example/assets/simple/mask_with_use2.svg rename to third_party/packages/flutter_svg/example/assets/simple/mask_with_use2.svg diff --git a/third_party/example/assets/simple/nested_group.svg b/third_party/packages/flutter_svg/example/assets/simple/nested_group.svg similarity index 100% rename from third_party/example/assets/simple/nested_group.svg rename to third_party/packages/flutter_svg/example/assets/simple/nested_group.svg diff --git a/third_party/example/assets/simple/opacity_on_path.svg b/third_party/packages/flutter_svg/example/assets/simple/opacity_on_path.svg similarity index 100% rename from third_party/example/assets/simple/opacity_on_path.svg rename to third_party/packages/flutter_svg/example/assets/simple/opacity_on_path.svg diff --git a/third_party/example/assets/simple/radial_gradient.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient.svg similarity index 100% rename from third_party/example/assets/simple/radial_gradient.svg rename to third_party/packages/flutter_svg/example/assets/simple/radial_gradient.svg diff --git a/third_party/example/assets/simple/radial_gradient_absolute_user_space_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_absolute_user_space_translate.svg similarity index 100% rename from third_party/example/assets/simple/radial_gradient_absolute_user_space_translate.svg rename to third_party/packages/flutter_svg/example/assets/simple/radial_gradient_absolute_user_space_translate.svg diff --git a/third_party/example/assets/simple/radial_gradient_focal.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_focal.svg similarity index 100% rename from third_party/example/assets/simple/radial_gradient_focal.svg rename to third_party/packages/flutter_svg/example/assets/simple/radial_gradient_focal.svg diff --git a/third_party/example/assets/simple/radial_gradient_percentage_bounding_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_percentage_bounding_translate.svg similarity index 100% rename from third_party/example/assets/simple/radial_gradient_percentage_bounding_translate.svg rename to third_party/packages/flutter_svg/example/assets/simple/radial_gradient_percentage_bounding_translate.svg diff --git a/third_party/example/assets/simple/radial_gradient_percentage_user_space_translate.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_percentage_user_space_translate.svg similarity index 100% rename from third_party/example/assets/simple/radial_gradient_percentage_user_space_translate.svg rename to third_party/packages/flutter_svg/example/assets/simple/radial_gradient_percentage_user_space_translate.svg diff --git a/third_party/example/assets/simple/radial_gradient_xlink.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_gradient_xlink.svg similarity index 100% rename from third_party/example/assets/simple/radial_gradient_xlink.svg rename to third_party/packages/flutter_svg/example/assets/simple/radial_gradient_xlink.svg diff --git a/third_party/example/assets/simple/radial_ref_linear_gradient.svg b/third_party/packages/flutter_svg/example/assets/simple/radial_ref_linear_gradient.svg similarity index 100% rename from third_party/example/assets/simple/radial_ref_linear_gradient.svg rename to third_party/packages/flutter_svg/example/assets/simple/radial_ref_linear_gradient.svg diff --git a/third_party/example/assets/simple/rect_rrect.svg b/third_party/packages/flutter_svg/example/assets/simple/rect_rrect.svg similarity index 100% rename from third_party/example/assets/simple/rect_rrect.svg rename to third_party/packages/flutter_svg/example/assets/simple/rect_rrect.svg diff --git a/third_party/example/assets/simple/rect_rrect_no_ry.svg b/third_party/packages/flutter_svg/example/assets/simple/rect_rrect_no_ry.svg similarity index 100% rename from third_party/example/assets/simple/rect_rrect_no_ry.svg rename to third_party/packages/flutter_svg/example/assets/simple/rect_rrect_no_ry.svg diff --git a/third_party/example/assets/simple/stroke_inherit_circles.svg b/third_party/packages/flutter_svg/example/assets/simple/stroke_inherit_circles.svg similarity index 100% rename from third_party/example/assets/simple/stroke_inherit_circles.svg rename to third_party/packages/flutter_svg/example/assets/simple/stroke_inherit_circles.svg diff --git a/third_party/example/assets/simple/style_attr.svg b/third_party/packages/flutter_svg/example/assets/simple/style_attr.svg similarity index 100% rename from third_party/example/assets/simple/style_attr.svg rename to third_party/packages/flutter_svg/example/assets/simple/style_attr.svg diff --git a/third_party/example/assets/simple/text.svg b/third_party/packages/flutter_svg/example/assets/simple/text.svg similarity index 100% rename from third_party/example/assets/simple/text.svg rename to third_party/packages/flutter_svg/example/assets/simple/text.svg diff --git a/third_party/example/assets/simple/text_2.svg b/third_party/packages/flutter_svg/example/assets/simple/text_2.svg similarity index 100% rename from third_party/example/assets/simple/text_2.svg rename to third_party/packages/flutter_svg/example/assets/simple/text_2.svg diff --git a/third_party/example/assets/simple/text_3.svg b/third_party/packages/flutter_svg/example/assets/simple/text_3.svg similarity index 100% rename from third_party/example/assets/simple/text_3.svg rename to third_party/packages/flutter_svg/example/assets/simple/text_3.svg diff --git a/third_party/example/assets/simple/text_4.svg b/third_party/packages/flutter_svg/example/assets/simple/text_4.svg similarity index 100% rename from third_party/example/assets/simple/text_4.svg rename to third_party/packages/flutter_svg/example/assets/simple/text_4.svg diff --git a/third_party/example/assets/simple/text_5.svg b/third_party/packages/flutter_svg/example/assets/simple/text_5.svg similarity index 100% rename from third_party/example/assets/simple/text_5.svg rename to third_party/packages/flutter_svg/example/assets/simple/text_5.svg diff --git a/third_party/example/assets/simple/text_6.svg b/third_party/packages/flutter_svg/example/assets/simple/text_6.svg similarity index 100% rename from third_party/example/assets/simple/text_6.svg rename to third_party/packages/flutter_svg/example/assets/simple/text_6.svg diff --git a/third_party/example/assets/simple/use_circles.svg b/third_party/packages/flutter_svg/example/assets/simple/use_circles.svg similarity index 100% rename from third_party/example/assets/simple/use_circles.svg rename to third_party/packages/flutter_svg/example/assets/simple/use_circles.svg diff --git a/third_party/example/assets/simple/use_circles_def.svg b/third_party/packages/flutter_svg/example/assets/simple/use_circles_def.svg similarity index 100% rename from third_party/example/assets/simple/use_circles_def.svg rename to third_party/packages/flutter_svg/example/assets/simple/use_circles_def.svg diff --git a/third_party/example/assets/simple/use_emc2.svg b/third_party/packages/flutter_svg/example/assets/simple/use_emc2.svg similarity index 100% rename from third_party/example/assets/simple/use_emc2.svg rename to third_party/packages/flutter_svg/example/assets/simple/use_emc2.svg diff --git a/third_party/example/assets/simple/use_fill.svg b/third_party/packages/flutter_svg/example/assets/simple/use_fill.svg similarity index 100% rename from third_party/example/assets/simple/use_fill.svg rename to third_party/packages/flutter_svg/example/assets/simple/use_fill.svg diff --git a/third_party/example/assets/simple/use_fill_test.svg b/third_party/packages/flutter_svg/example/assets/simple/use_fill_test.svg similarity index 100% rename from third_party/example/assets/simple/use_fill_test.svg rename to third_party/packages/flutter_svg/example/assets/simple/use_fill_test.svg diff --git a/third_party/example/assets/simple/use_opacity_grid.svg b/third_party/packages/flutter_svg/example/assets/simple/use_opacity_grid.svg similarity index 100% rename from third_party/example/assets/simple/use_opacity_grid.svg rename to third_party/packages/flutter_svg/example/assets/simple/use_opacity_grid.svg diff --git a/third_party/example/assets/simple/width_height_viewbox.svg b/third_party/packages/flutter_svg/example/assets/simple/width_height_viewbox.svg similarity index 100% rename from third_party/example/assets/simple/width_height_viewbox.svg rename to third_party/packages/flutter_svg/example/assets/simple/width_height_viewbox.svg diff --git a/third_party/example/assets/simple/zero_width_strokes.svg b/third_party/packages/flutter_svg/example/assets/simple/zero_width_strokes.svg similarity index 100% rename from third_party/example/assets/simple/zero_width_strokes.svg rename to third_party/packages/flutter_svg/example/assets/simple/zero_width_strokes.svg diff --git a/third_party/example/assets/svg_currentcolor.svg b/third_party/packages/flutter_svg/example/assets/svg_currentcolor.svg similarity index 100% rename from third_party/example/assets/svg_currentcolor.svg rename to third_party/packages/flutter_svg/example/assets/svg_currentcolor.svg diff --git a/third_party/example/assets/text_transform.svg b/third_party/packages/flutter_svg/example/assets/text_transform.svg similarity index 100% rename from third_party/example/assets/text_transform.svg rename to third_party/packages/flutter_svg/example/assets/text_transform.svg diff --git a/third_party/example/assets/w3samples/aa.svg b/third_party/packages/flutter_svg/example/assets/w3samples/aa.svg similarity index 100% rename from third_party/example/assets/w3samples/aa.svg rename to third_party/packages/flutter_svg/example/assets/w3samples/aa.svg diff --git a/third_party/example/assets/w3samples/alphachannel.svg b/third_party/packages/flutter_svg/example/assets/w3samples/alphachannel.svg similarity index 100% rename from third_party/example/assets/w3samples/alphachannel.svg rename to third_party/packages/flutter_svg/example/assets/w3samples/alphachannel.svg diff --git a/third_party/example/assets/wikimedia/Firefox_Logo_2017.svg b/third_party/packages/flutter_svg/example/assets/wikimedia/Firefox_Logo_2017.svg similarity index 100% rename from third_party/example/assets/wikimedia/Firefox_Logo_2017.svg rename to third_party/packages/flutter_svg/example/assets/wikimedia/Firefox_Logo_2017.svg diff --git a/third_party/example/assets/wikimedia/Flag_of_the_United_States.svg b/third_party/packages/flutter_svg/example/assets/wikimedia/Flag_of_the_United_States.svg similarity index 100% rename from third_party/example/assets/wikimedia/Flag_of_the_United_States.svg rename to third_party/packages/flutter_svg/example/assets/wikimedia/Flag_of_the_United_States.svg diff --git a/third_party/example/assets/wikimedia/Ghostscript_Tiger.svg b/third_party/packages/flutter_svg/example/assets/wikimedia/Ghostscript_Tiger.svg similarity index 100% rename from third_party/example/assets/wikimedia/Ghostscript_Tiger.svg rename to third_party/packages/flutter_svg/example/assets/wikimedia/Ghostscript_Tiger.svg diff --git a/third_party/example/assets/wikimedia/chess_knight.svg b/third_party/packages/flutter_svg/example/assets/wikimedia/chess_knight.svg similarity index 100% rename from third_party/example/assets/wikimedia/chess_knight.svg rename to third_party/packages/flutter_svg/example/assets/wikimedia/chess_knight.svg diff --git a/third_party/example/example.iml b/third_party/packages/flutter_svg/example/example.iml similarity index 100% rename from third_party/example/example.iml rename to third_party/packages/flutter_svg/example/example.iml diff --git a/third_party/example/example_android.iml b/third_party/packages/flutter_svg/example/example_android.iml similarity index 100% rename from third_party/example/example_android.iml rename to third_party/packages/flutter_svg/example/example_android.iml diff --git a/third_party/example/ios/.gitignore b/third_party/packages/flutter_svg/example/ios/.gitignore similarity index 100% rename from third_party/example/ios/.gitignore rename to third_party/packages/flutter_svg/example/ios/.gitignore diff --git a/third_party/example/ios/Flutter/AppFrameworkInfo.plist b/third_party/packages/flutter_svg/example/ios/Flutter/AppFrameworkInfo.plist similarity index 100% rename from third_party/example/ios/Flutter/AppFrameworkInfo.plist rename to third_party/packages/flutter_svg/example/ios/Flutter/AppFrameworkInfo.plist diff --git a/third_party/example/ios/Flutter/Debug.xcconfig b/third_party/packages/flutter_svg/example/ios/Flutter/Debug.xcconfig similarity index 100% rename from third_party/example/ios/Flutter/Debug.xcconfig rename to third_party/packages/flutter_svg/example/ios/Flutter/Debug.xcconfig diff --git a/third_party/example/ios/Flutter/Release.xcconfig b/third_party/packages/flutter_svg/example/ios/Flutter/Release.xcconfig similarity index 100% rename from third_party/example/ios/Flutter/Release.xcconfig rename to third_party/packages/flutter_svg/example/ios/Flutter/Release.xcconfig diff --git a/third_party/example/ios/Runner.xcodeproj/project.pbxproj b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.pbxproj similarity index 100% rename from third_party/example/ios/Runner.xcodeproj/project.pbxproj rename to third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.pbxproj diff --git a/third_party/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata similarity index 100% rename from third_party/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata diff --git a/third_party/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from third_party/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/third_party/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings similarity index 100% rename from third_party/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings rename to third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/third_party/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from third_party/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to third_party/packages/flutter_svg/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/third_party/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from third_party/example/ios/Runner.xcworkspace/contents.xcworkspacedata rename to third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/contents.xcworkspacedata diff --git a/third_party/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from third_party/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/third_party/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings similarity index 100% rename from third_party/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings rename to third_party/packages/flutter_svg/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings diff --git a/third_party/example/ios/Runner/AppDelegate.h b/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.h similarity index 100% rename from third_party/example/ios/Runner/AppDelegate.h rename to third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.h diff --git a/third_party/example/ios/Runner/AppDelegate.m b/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.m similarity index 100% rename from third_party/example/ios/Runner/AppDelegate.m rename to third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.m diff --git a/third_party/example/ios/Runner/AppDelegate.swift b/third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.swift similarity index 100% rename from third_party/example/ios/Runner/AppDelegate.swift rename to third_party/packages/flutter_svg/example/ios/Runner/AppDelegate.swift diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json diff --git a/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png diff --git a/third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md similarity index 100% rename from third_party/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md rename to third_party/packages/flutter_svg/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md diff --git a/third_party/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/third_party/packages/flutter_svg/example/ios/Runner/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from third_party/example/ios/Runner/Base.lproj/LaunchScreen.storyboard rename to third_party/packages/flutter_svg/example/ios/Runner/Base.lproj/LaunchScreen.storyboard diff --git a/third_party/example/ios/Runner/Base.lproj/Main.storyboard b/third_party/packages/flutter_svg/example/ios/Runner/Base.lproj/Main.storyboard similarity index 100% rename from third_party/example/ios/Runner/Base.lproj/Main.storyboard rename to third_party/packages/flutter_svg/example/ios/Runner/Base.lproj/Main.storyboard diff --git a/third_party/example/ios/Runner/Info.plist b/third_party/packages/flutter_svg/example/ios/Runner/Info.plist similarity index 100% rename from third_party/example/ios/Runner/Info.plist rename to third_party/packages/flutter_svg/example/ios/Runner/Info.plist diff --git a/third_party/example/ios/Runner/Runner-Bridging-Header.h b/third_party/packages/flutter_svg/example/ios/Runner/Runner-Bridging-Header.h similarity index 100% rename from third_party/example/ios/Runner/Runner-Bridging-Header.h rename to third_party/packages/flutter_svg/example/ios/Runner/Runner-Bridging-Header.h diff --git a/third_party/example/ios/Runner/main.m b/third_party/packages/flutter_svg/example/ios/Runner/main.m similarity index 100% rename from third_party/example/ios/Runner/main.m rename to third_party/packages/flutter_svg/example/ios/Runner/main.m diff --git a/third_party/example/lib/main.dart b/third_party/packages/flutter_svg/example/lib/main.dart similarity index 100% rename from third_party/example/lib/main.dart rename to third_party/packages/flutter_svg/example/lib/main.dart diff --git a/third_party/example/lib/simple.dart b/third_party/packages/flutter_svg/example/lib/simple.dart similarity index 100% rename from third_party/example/lib/simple.dart rename to third_party/packages/flutter_svg/example/lib/simple.dart diff --git a/third_party/example/linux/.gitignore b/third_party/packages/flutter_svg/example/linux/.gitignore similarity index 100% rename from third_party/example/linux/.gitignore rename to third_party/packages/flutter_svg/example/linux/.gitignore diff --git a/third_party/example/linux/CMakeLists.txt b/third_party/packages/flutter_svg/example/linux/CMakeLists.txt similarity index 100% rename from third_party/example/linux/CMakeLists.txt rename to third_party/packages/flutter_svg/example/linux/CMakeLists.txt diff --git a/third_party/example/linux/flutter/CMakeLists.txt b/third_party/packages/flutter_svg/example/linux/flutter/CMakeLists.txt similarity index 100% rename from third_party/example/linux/flutter/CMakeLists.txt rename to third_party/packages/flutter_svg/example/linux/flutter/CMakeLists.txt diff --git a/third_party/example/linux/flutter/generated_plugin_registrant.cc b/third_party/packages/flutter_svg/example/linux/flutter/generated_plugin_registrant.cc similarity index 100% rename from third_party/example/linux/flutter/generated_plugin_registrant.cc rename to third_party/packages/flutter_svg/example/linux/flutter/generated_plugin_registrant.cc diff --git a/third_party/example/linux/flutter/generated_plugin_registrant.h b/third_party/packages/flutter_svg/example/linux/flutter/generated_plugin_registrant.h similarity index 100% rename from third_party/example/linux/flutter/generated_plugin_registrant.h rename to third_party/packages/flutter_svg/example/linux/flutter/generated_plugin_registrant.h diff --git a/third_party/example/linux/flutter/generated_plugins.cmake b/third_party/packages/flutter_svg/example/linux/flutter/generated_plugins.cmake similarity index 100% rename from third_party/example/linux/flutter/generated_plugins.cmake rename to third_party/packages/flutter_svg/example/linux/flutter/generated_plugins.cmake diff --git a/third_party/example/linux/main.cc b/third_party/packages/flutter_svg/example/linux/main.cc similarity index 100% rename from third_party/example/linux/main.cc rename to third_party/packages/flutter_svg/example/linux/main.cc diff --git a/third_party/example/linux/my_application.cc b/third_party/packages/flutter_svg/example/linux/my_application.cc similarity index 100% rename from third_party/example/linux/my_application.cc rename to third_party/packages/flutter_svg/example/linux/my_application.cc diff --git a/third_party/example/linux/my_application.h b/third_party/packages/flutter_svg/example/linux/my_application.h similarity index 100% rename from third_party/example/linux/my_application.h rename to third_party/packages/flutter_svg/example/linux/my_application.h diff --git a/third_party/example/macos/.gitignore b/third_party/packages/flutter_svg/example/macos/.gitignore similarity index 100% rename from third_party/example/macos/.gitignore rename to third_party/packages/flutter_svg/example/macos/.gitignore diff --git a/third_party/example/macos/Flutter/Flutter-Debug.xcconfig b/third_party/packages/flutter_svg/example/macos/Flutter/Flutter-Debug.xcconfig similarity index 100% rename from third_party/example/macos/Flutter/Flutter-Debug.xcconfig rename to third_party/packages/flutter_svg/example/macos/Flutter/Flutter-Debug.xcconfig diff --git a/third_party/example/macos/Flutter/Flutter-Release.xcconfig b/third_party/packages/flutter_svg/example/macos/Flutter/Flutter-Release.xcconfig similarity index 100% rename from third_party/example/macos/Flutter/Flutter-Release.xcconfig rename to third_party/packages/flutter_svg/example/macos/Flutter/Flutter-Release.xcconfig diff --git a/third_party/example/macos/Flutter/GeneratedPluginRegistrant.swift b/third_party/packages/flutter_svg/example/macos/Flutter/GeneratedPluginRegistrant.swift similarity index 100% rename from third_party/example/macos/Flutter/GeneratedPluginRegistrant.swift rename to third_party/packages/flutter_svg/example/macos/Flutter/GeneratedPluginRegistrant.swift diff --git a/third_party/example/macos/Runner.xcodeproj/project.pbxproj b/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/project.pbxproj similarity index 100% rename from third_party/example/macos/Runner.xcodeproj/project.pbxproj rename to third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/project.pbxproj diff --git a/third_party/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from third_party/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/third_party/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme similarity index 100% rename from third_party/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme rename to third_party/packages/flutter_svg/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme diff --git a/third_party/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/third_party/packages/flutter_svg/example/macos/Runner.xcworkspace/contents.xcworkspacedata similarity index 100% rename from third_party/example/macos/Runner.xcworkspace/contents.xcworkspacedata rename to third_party/packages/flutter_svg/example/macos/Runner.xcworkspace/contents.xcworkspacedata diff --git a/third_party/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/third_party/packages/flutter_svg/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist similarity index 100% rename from third_party/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to third_party/packages/flutter_svg/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/third_party/example/macos/Runner/AppDelegate.swift b/third_party/packages/flutter_svg/example/macos/Runner/AppDelegate.swift similarity index 100% rename from third_party/example/macos/Runner/AppDelegate.swift rename to third_party/packages/flutter_svg/example/macos/Runner/AppDelegate.swift diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json similarity index 100% rename from third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json rename to third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png similarity index 100% rename from third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png rename to third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png similarity index 100% rename from third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png rename to third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png similarity index 100% rename from third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png rename to third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png similarity index 100% rename from third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png rename to third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png similarity index 100% rename from third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png rename to third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png similarity index 100% rename from third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png rename to third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png diff --git a/third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png b/third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png similarity index 100% rename from third_party/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png rename to third_party/packages/flutter_svg/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png diff --git a/third_party/example/macos/Runner/Base.lproj/MainMenu.xib b/third_party/packages/flutter_svg/example/macos/Runner/Base.lproj/MainMenu.xib similarity index 100% rename from third_party/example/macos/Runner/Base.lproj/MainMenu.xib rename to third_party/packages/flutter_svg/example/macos/Runner/Base.lproj/MainMenu.xib diff --git a/third_party/example/macos/Runner/Configs/AppInfo.xcconfig b/third_party/packages/flutter_svg/example/macos/Runner/Configs/AppInfo.xcconfig similarity index 100% rename from third_party/example/macos/Runner/Configs/AppInfo.xcconfig rename to third_party/packages/flutter_svg/example/macos/Runner/Configs/AppInfo.xcconfig diff --git a/third_party/example/macos/Runner/Configs/Debug.xcconfig b/third_party/packages/flutter_svg/example/macos/Runner/Configs/Debug.xcconfig similarity index 100% rename from third_party/example/macos/Runner/Configs/Debug.xcconfig rename to third_party/packages/flutter_svg/example/macos/Runner/Configs/Debug.xcconfig diff --git a/third_party/example/macos/Runner/Configs/Release.xcconfig b/third_party/packages/flutter_svg/example/macos/Runner/Configs/Release.xcconfig similarity index 100% rename from third_party/example/macos/Runner/Configs/Release.xcconfig rename to third_party/packages/flutter_svg/example/macos/Runner/Configs/Release.xcconfig diff --git a/third_party/example/macos/Runner/Configs/Warnings.xcconfig b/third_party/packages/flutter_svg/example/macos/Runner/Configs/Warnings.xcconfig similarity index 100% rename from third_party/example/macos/Runner/Configs/Warnings.xcconfig rename to third_party/packages/flutter_svg/example/macos/Runner/Configs/Warnings.xcconfig diff --git a/third_party/example/macos/Runner/DebugProfile.entitlements b/third_party/packages/flutter_svg/example/macos/Runner/DebugProfile.entitlements similarity index 100% rename from third_party/example/macos/Runner/DebugProfile.entitlements rename to third_party/packages/flutter_svg/example/macos/Runner/DebugProfile.entitlements diff --git a/third_party/example/macos/Runner/Info.plist b/third_party/packages/flutter_svg/example/macos/Runner/Info.plist similarity index 100% rename from third_party/example/macos/Runner/Info.plist rename to third_party/packages/flutter_svg/example/macos/Runner/Info.plist diff --git a/third_party/example/macos/Runner/MainFlutterWindow.swift b/third_party/packages/flutter_svg/example/macos/Runner/MainFlutterWindow.swift similarity index 100% rename from third_party/example/macos/Runner/MainFlutterWindow.swift rename to third_party/packages/flutter_svg/example/macos/Runner/MainFlutterWindow.swift diff --git a/third_party/example/macos/Runner/Release.entitlements b/third_party/packages/flutter_svg/example/macos/Runner/Release.entitlements similarity index 100% rename from third_party/example/macos/Runner/Release.entitlements rename to third_party/packages/flutter_svg/example/macos/Runner/Release.entitlements diff --git a/third_party/example/pubspec.yaml b/third_party/packages/flutter_svg/example/pubspec.yaml similarity index 100% rename from third_party/example/pubspec.yaml rename to third_party/packages/flutter_svg/example/pubspec.yaml diff --git a/third_party/example/test_driver/bench.dart b/third_party/packages/flutter_svg/example/test_driver/bench.dart similarity index 100% rename from third_party/example/test_driver/bench.dart rename to third_party/packages/flutter_svg/example/test_driver/bench.dart diff --git a/third_party/example/test_driver/bench_test.dart b/third_party/packages/flutter_svg/example/test_driver/bench_test.dart similarity index 100% rename from third_party/example/test_driver/bench_test.dart rename to third_party/packages/flutter_svg/example/test_driver/bench_test.dart diff --git a/third_party/example/test_driver/repaint.dart b/third_party/packages/flutter_svg/example/test_driver/repaint.dart similarity index 100% rename from third_party/example/test_driver/repaint.dart rename to third_party/packages/flutter_svg/example/test_driver/repaint.dart diff --git a/third_party/example/test_driver/repaint_test.dart b/third_party/packages/flutter_svg/example/test_driver/repaint_test.dart similarity index 100% rename from third_party/example/test_driver/repaint_test.dart rename to third_party/packages/flutter_svg/example/test_driver/repaint_test.dart diff --git a/third_party/example/web/favicon.png b/third_party/packages/flutter_svg/example/web/favicon.png similarity index 100% rename from third_party/example/web/favicon.png rename to third_party/packages/flutter_svg/example/web/favicon.png diff --git a/third_party/example/web/icons/Icon-192.png b/third_party/packages/flutter_svg/example/web/icons/Icon-192.png similarity index 100% rename from third_party/example/web/icons/Icon-192.png rename to third_party/packages/flutter_svg/example/web/icons/Icon-192.png diff --git a/third_party/example/web/icons/Icon-512.png b/third_party/packages/flutter_svg/example/web/icons/Icon-512.png similarity index 100% rename from third_party/example/web/icons/Icon-512.png rename to third_party/packages/flutter_svg/example/web/icons/Icon-512.png diff --git a/third_party/example/web/icons/Icon-maskable-192.png b/third_party/packages/flutter_svg/example/web/icons/Icon-maskable-192.png similarity index 100% rename from third_party/example/web/icons/Icon-maskable-192.png rename to third_party/packages/flutter_svg/example/web/icons/Icon-maskable-192.png diff --git a/third_party/example/web/icons/Icon-maskable-512.png b/third_party/packages/flutter_svg/example/web/icons/Icon-maskable-512.png similarity index 100% rename from third_party/example/web/icons/Icon-maskable-512.png rename to third_party/packages/flutter_svg/example/web/icons/Icon-maskable-512.png diff --git a/third_party/example/web/index.html b/third_party/packages/flutter_svg/example/web/index.html similarity index 100% rename from third_party/example/web/index.html rename to third_party/packages/flutter_svg/example/web/index.html diff --git a/third_party/example/web/manifest.json b/third_party/packages/flutter_svg/example/web/manifest.json similarity index 100% rename from third_party/example/web/manifest.json rename to third_party/packages/flutter_svg/example/web/manifest.json diff --git a/third_party/example/windows/.gitignore b/third_party/packages/flutter_svg/example/windows/.gitignore similarity index 100% rename from third_party/example/windows/.gitignore rename to third_party/packages/flutter_svg/example/windows/.gitignore diff --git a/third_party/example/windows/CMakeLists.txt b/third_party/packages/flutter_svg/example/windows/CMakeLists.txt similarity index 100% rename from third_party/example/windows/CMakeLists.txt rename to third_party/packages/flutter_svg/example/windows/CMakeLists.txt diff --git a/third_party/example/windows/flutter/CMakeLists.txt b/third_party/packages/flutter_svg/example/windows/flutter/CMakeLists.txt similarity index 100% rename from third_party/example/windows/flutter/CMakeLists.txt rename to third_party/packages/flutter_svg/example/windows/flutter/CMakeLists.txt diff --git a/third_party/example/windows/flutter/generated_plugin_registrant.cc b/third_party/packages/flutter_svg/example/windows/flutter/generated_plugin_registrant.cc similarity index 100% rename from third_party/example/windows/flutter/generated_plugin_registrant.cc rename to third_party/packages/flutter_svg/example/windows/flutter/generated_plugin_registrant.cc diff --git a/third_party/example/windows/flutter/generated_plugin_registrant.h b/third_party/packages/flutter_svg/example/windows/flutter/generated_plugin_registrant.h similarity index 100% rename from third_party/example/windows/flutter/generated_plugin_registrant.h rename to third_party/packages/flutter_svg/example/windows/flutter/generated_plugin_registrant.h diff --git a/third_party/example/windows/flutter/generated_plugins.cmake b/third_party/packages/flutter_svg/example/windows/flutter/generated_plugins.cmake similarity index 100% rename from third_party/example/windows/flutter/generated_plugins.cmake rename to third_party/packages/flutter_svg/example/windows/flutter/generated_plugins.cmake diff --git a/third_party/example/windows/runner/CMakeLists.txt b/third_party/packages/flutter_svg/example/windows/runner/CMakeLists.txt similarity index 100% rename from third_party/example/windows/runner/CMakeLists.txt rename to third_party/packages/flutter_svg/example/windows/runner/CMakeLists.txt diff --git a/third_party/example/windows/runner/Runner.rc b/third_party/packages/flutter_svg/example/windows/runner/Runner.rc similarity index 100% rename from third_party/example/windows/runner/Runner.rc rename to third_party/packages/flutter_svg/example/windows/runner/Runner.rc diff --git a/third_party/example/windows/runner/flutter_window.cpp b/third_party/packages/flutter_svg/example/windows/runner/flutter_window.cpp similarity index 100% rename from third_party/example/windows/runner/flutter_window.cpp rename to third_party/packages/flutter_svg/example/windows/runner/flutter_window.cpp diff --git a/third_party/example/windows/runner/flutter_window.h b/third_party/packages/flutter_svg/example/windows/runner/flutter_window.h similarity index 100% rename from third_party/example/windows/runner/flutter_window.h rename to third_party/packages/flutter_svg/example/windows/runner/flutter_window.h diff --git a/third_party/example/windows/runner/main.cpp b/third_party/packages/flutter_svg/example/windows/runner/main.cpp similarity index 100% rename from third_party/example/windows/runner/main.cpp rename to third_party/packages/flutter_svg/example/windows/runner/main.cpp diff --git a/third_party/example/windows/runner/resource.h b/third_party/packages/flutter_svg/example/windows/runner/resource.h similarity index 100% rename from third_party/example/windows/runner/resource.h rename to third_party/packages/flutter_svg/example/windows/runner/resource.h diff --git a/third_party/example/windows/runner/resources/app_icon.ico b/third_party/packages/flutter_svg/example/windows/runner/resources/app_icon.ico similarity index 100% rename from third_party/example/windows/runner/resources/app_icon.ico rename to third_party/packages/flutter_svg/example/windows/runner/resources/app_icon.ico diff --git a/third_party/example/windows/runner/run_loop.cpp b/third_party/packages/flutter_svg/example/windows/runner/run_loop.cpp similarity index 100% rename from third_party/example/windows/runner/run_loop.cpp rename to third_party/packages/flutter_svg/example/windows/runner/run_loop.cpp diff --git a/third_party/example/windows/runner/run_loop.h b/third_party/packages/flutter_svg/example/windows/runner/run_loop.h similarity index 100% rename from third_party/example/windows/runner/run_loop.h rename to third_party/packages/flutter_svg/example/windows/runner/run_loop.h diff --git a/third_party/example/windows/runner/runner.exe.manifest b/third_party/packages/flutter_svg/example/windows/runner/runner.exe.manifest similarity index 100% rename from third_party/example/windows/runner/runner.exe.manifest rename to third_party/packages/flutter_svg/example/windows/runner/runner.exe.manifest diff --git a/third_party/example/windows/runner/utils.cpp b/third_party/packages/flutter_svg/example/windows/runner/utils.cpp similarity index 100% rename from third_party/example/windows/runner/utils.cpp rename to third_party/packages/flutter_svg/example/windows/runner/utils.cpp diff --git a/third_party/example/windows/runner/utils.h b/third_party/packages/flutter_svg/example/windows/runner/utils.h similarity index 100% rename from third_party/example/windows/runner/utils.h rename to third_party/packages/flutter_svg/example/windows/runner/utils.h diff --git a/third_party/example/windows/runner/win32_window.cpp b/third_party/packages/flutter_svg/example/windows/runner/win32_window.cpp similarity index 100% rename from third_party/example/windows/runner/win32_window.cpp rename to third_party/packages/flutter_svg/example/windows/runner/win32_window.cpp diff --git a/third_party/example/windows/runner/win32_window.h b/third_party/packages/flutter_svg/example/windows/runner/win32_window.h similarity index 100% rename from third_party/example/windows/runner/win32_window.h rename to third_party/packages/flutter_svg/example/windows/runner/win32_window.h diff --git a/third_party/flutter_svg.iml b/third_party/packages/flutter_svg/flutter_svg.iml similarity index 100% rename from third_party/flutter_svg.iml rename to third_party/packages/flutter_svg/flutter_svg.iml diff --git a/third_party/flutter_svg_android.iml b/third_party/packages/flutter_svg/flutter_svg_android.iml similarity index 100% rename from third_party/flutter_svg_android.iml rename to third_party/packages/flutter_svg/flutter_svg_android.iml diff --git a/third_party/lib/flutter_svg.dart b/third_party/packages/flutter_svg/lib/flutter_svg.dart similarity index 100% rename from third_party/lib/flutter_svg.dart rename to third_party/packages/flutter_svg/lib/flutter_svg.dart diff --git a/third_party/lib/src/cache.dart b/third_party/packages/flutter_svg/lib/src/cache.dart similarity index 100% rename from third_party/lib/src/cache.dart rename to third_party/packages/flutter_svg/lib/src/cache.dart diff --git a/third_party/lib/src/loaders.dart b/third_party/packages/flutter_svg/lib/src/loaders.dart similarity index 100% rename from third_party/lib/src/loaders.dart rename to third_party/packages/flutter_svg/lib/src/loaders.dart diff --git a/third_party/lib/src/utilities/_file_io.dart b/third_party/packages/flutter_svg/lib/src/utilities/_file_io.dart similarity index 100% rename from third_party/lib/src/utilities/_file_io.dart rename to third_party/packages/flutter_svg/lib/src/utilities/_file_io.dart diff --git a/third_party/lib/src/utilities/_file_none.dart b/third_party/packages/flutter_svg/lib/src/utilities/_file_none.dart similarity index 100% rename from third_party/lib/src/utilities/_file_none.dart rename to third_party/packages/flutter_svg/lib/src/utilities/_file_none.dart diff --git a/third_party/lib/src/utilities/_http_io.dart b/third_party/packages/flutter_svg/lib/src/utilities/_http_io.dart similarity index 100% rename from third_party/lib/src/utilities/_http_io.dart rename to third_party/packages/flutter_svg/lib/src/utilities/_http_io.dart diff --git a/third_party/lib/src/utilities/_http_web.dart b/third_party/packages/flutter_svg/lib/src/utilities/_http_web.dart similarity index 100% rename from third_party/lib/src/utilities/_http_web.dart rename to third_party/packages/flutter_svg/lib/src/utilities/_http_web.dart diff --git a/third_party/lib/src/utilities/compute.dart b/third_party/packages/flutter_svg/lib/src/utilities/compute.dart similarity index 100% rename from third_party/lib/src/utilities/compute.dart rename to third_party/packages/flutter_svg/lib/src/utilities/compute.dart diff --git a/third_party/lib/src/utilities/file.dart b/third_party/packages/flutter_svg/lib/src/utilities/file.dart similarity index 100% rename from third_party/lib/src/utilities/file.dart rename to third_party/packages/flutter_svg/lib/src/utilities/file.dart diff --git a/third_party/lib/src/utilities/http.dart b/third_party/packages/flutter_svg/lib/src/utilities/http.dart similarity index 100% rename from third_party/lib/src/utilities/http.dart rename to third_party/packages/flutter_svg/lib/src/utilities/http.dart diff --git a/third_party/lib/src/utilities/numbers.dart b/third_party/packages/flutter_svg/lib/src/utilities/numbers.dart similarity index 100% rename from third_party/lib/src/utilities/numbers.dart rename to third_party/packages/flutter_svg/lib/src/utilities/numbers.dart diff --git a/third_party/lib/svg.dart b/third_party/packages/flutter_svg/lib/svg.dart similarity index 100% rename from third_party/lib/svg.dart rename to third_party/packages/flutter_svg/lib/svg.dart diff --git a/third_party/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml similarity index 90% rename from third_party/pubspec.yaml rename to third_party/packages/flutter_svg/pubspec.yaml index 6801822a168e..fbf18e770a5d 100644 --- a/third_party/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. -repository: https://github.com/dnfield/flutter_svg +repository: https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues version: 2.0.5 diff --git a/third_party/test/cache_test.dart b/third_party/packages/flutter_svg/test/cache_test.dart similarity index 100% rename from third_party/test/cache_test.dart rename to third_party/packages/flutter_svg/test/cache_test.dart diff --git a/third_party/packages/flutter_svg/test/failures/text_color_filter_isolatedDiff.png b/third_party/packages/flutter_svg/test/failures/text_color_filter_isolatedDiff.png new file mode 100644 index 0000000000000000000000000000000000000000..a7b0e37514ac83ab1041e907949218f5592541ad GIT binary patch literal 2247 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzEX7WqAsj$Z!;#X#z`#-G z>EaktG3V`dN8UpW0t}8$6PkN=tzU7NY5qG_tHlZXe^&rC4OK8<*39o^%nWx97Fz?o zu!EnOiGd-7hl7D(f}sKfgTt`~ps3`iASgg8bJ-d8C#LniZR?(Un-Lf;qhK@yMnhmU z1V%#udk7q;p8={|KJ0y722@ZW&&I;Qa6&?Wfk7eJfq|i+hY?ta8jT8q0_5{8J_d$$ lrpCw14j(=D77?5c2iVOH^844-30wdPdb;|#taD0e0swHXiqrrA literal 0 HcmV?d00001 diff --git a/third_party/packages/flutter_svg/test/failures/text_color_filter_maskedDiff.png b/third_party/packages/flutter_svg/test/failures/text_color_filter_maskedDiff.png new file mode 100644 index 0000000000000000000000000000000000000000..29981f0358e7ef49b05257510617b9e30bfcc942 GIT binary patch literal 2421 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzEX7WqAsj$Z!;#X#z`&{F z>EaktG3V`_y}45zMO-ghiz$_Hnj~}zITXov9NFlts9L1`WXY2)4Z*@SDlKC6LizoF zBUU#}&Wk;J258(61tr(sF&_B*q43#_y$`44^*zp7`!)4DAA?1?_-=Nfm;UoJGBGfu zuy8OiOb}FHU~q720E$YE3W5S85*S414;RW@-)%nU#`CS${=O3g2F@rL4S~@R7!83T z6#{>jZmniuun8?Uo_;_5o~&{HwKGrO+5Wk8_RQ_O(hc{kH-cncfwKI@@z2vMWM+S7 znA6>Tmzm*#X4Q$n-cjfOH zEX?Z;GBvpGng6rQ{PU~CXJu#i*x7i1DjTYT2IFmI{0t0!uOFY;SbbRYuFUbPQLj(G zlRYqh=M7t+O+V^61Q-|;lpPot8hRKQ85oS1SQr>ij0%DRH_kHU?f}XB^F6*2UngHI{-(LU# literal 0 HcmV?d00001 diff --git a/third_party/test/golden_widget/text_color_filter.png b/third_party/packages/flutter_svg/test/failures/text_color_filter_masterImage.png similarity index 100% rename from third_party/test/golden_widget/text_color_filter.png rename to third_party/packages/flutter_svg/test/failures/text_color_filter_masterImage.png diff --git a/third_party/packages/flutter_svg/test/failures/text_color_filter_testImage.png b/third_party/packages/flutter_svg/test/failures/text_color_filter_testImage.png new file mode 100644 index 0000000000000000000000000000000000000000..20ea01b6daa35ee9087c6fea46d2b9302001805e GIT binary patch literal 2429 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI zLpXq-h9jkefq_%q)5S5QV$Rz;hJI55CE6~&XHPmS6w%~;ps7?sIO%Lq&dN0HcSklb z=NP8s=%{D)e2$Sg7kTiu-Or-;JV4`yCU8iPwq>Z0eV6`iwYkjYpJ%SVJ#+Y#EJMMo zb7A~IAKl|)WMW`QVc}q4m>{UYz~JE402GxR6$Ayy&InM@ZJRm!s&wDW%4daNK`Ct% zjE2By2#kinkP3l+2e(x*FzgB0J@d4@vHW-A>$lH5eP#RS-t(FKtIZke%Qk{!U4XL7 zXXby_w)ximoncPb=BvyM4^*pW?UWAZZ}{)mz;Gb(`f7HDIZCkFLFQZOSB8dQ6$gd~ z4dur1Y0rKGYnJ85^dlGw4lJK}{O*~nm(Sca`&{?l(TeJ!HD^QaR|bX$JJ2e&1NSX~ u^&JC4h4pBarhuzDf0hIeI;<62!vTNqBhs5H|K;2S#hIt8pUXO@geCwpCE_{& literal 0 HcmV?d00001 diff --git a/third_party/test/golden_widget/circle.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex.png similarity index 100% rename from third_party/test/golden_widget/circle.em_ex.png rename to third_party/packages/flutter_svg/test/golden_widget/circle.em_ex.png diff --git a/third_party/test/golden_widget/circle.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex2.png similarity index 100% rename from third_party/test/golden_widget/circle.em_ex2.png rename to third_party/packages/flutter_svg/test/golden_widget/circle.em_ex2.png diff --git a/third_party/test/golden_widget/columns_and_rows.png b/third_party/packages/flutter_svg/test/golden_widget/columns_and_rows.png similarity index 100% rename from third_party/test/golden_widget/columns_and_rows.png rename to third_party/packages/flutter_svg/test/golden_widget/columns_and_rows.png diff --git a/third_party/test/golden_widget/ellipse.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex.png similarity index 100% rename from third_party/test/golden_widget/ellipse.em_ex.png rename to third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex.png diff --git a/third_party/test/golden_widget/ellipse.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex2.png similarity index 100% rename from third_party/test/golden_widget/ellipse.em_ex2.png rename to third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex2.png diff --git a/third_party/test/golden_widget/flutter_logo.asset.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.asset.png similarity index 100% rename from third_party/test/golden_widget/flutter_logo.asset.png rename to third_party/packages/flutter_svg/test/golden_widget/flutter_logo.asset.png diff --git a/third_party/test/golden_widget/flutter_logo.memory.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.memory.png similarity index 100% rename from third_party/test/golden_widget/flutter_logo.memory.png rename to third_party/packages/flutter_svg/test/golden_widget/flutter_logo.memory.png diff --git a/third_party/test/golden_widget/flutter_logo.natural.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.natural.png similarity index 100% rename from third_party/test/golden_widget/flutter_logo.natural.png rename to third_party/packages/flutter_svg/test/golden_widget/flutter_logo.natural.png diff --git a/third_party/test/golden_widget/flutter_logo.network.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.network.png similarity index 100% rename from third_party/test/golden_widget/flutter_logo.network.png rename to third_party/packages/flutter_svg/test/golden_widget/flutter_logo.network.png diff --git a/third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png similarity index 100% rename from third_party/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png rename to third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.blendmode_color.png diff --git a/third_party/test/golden_widget/flutter_logo.string.color_filter.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.png similarity index 100% rename from third_party/test/golden_widget/flutter_logo.string.color_filter.png rename to third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.png diff --git a/third_party/test/golden_widget/flutter_logo.string.ltr.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.ltr.png similarity index 100% rename from third_party/test/golden_widget/flutter_logo.string.ltr.png rename to third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.ltr.png diff --git a/third_party/test/golden_widget/flutter_logo.string.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.png similarity index 100% rename from third_party/test/golden_widget/flutter_logo.string.png rename to third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.png diff --git a/third_party/test/golden_widget/flutter_logo.string.rtl.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.rtl.png similarity index 100% rename from third_party/test/golden_widget/flutter_logo.string.rtl.png rename to third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.rtl.png diff --git a/third_party/test/golden_widget/line.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/line.em_ex.png similarity index 100% rename from third_party/test/golden_widget/line.em_ex.png rename to third_party/packages/flutter_svg/test/golden_widget/line.em_ex.png diff --git a/third_party/test/golden_widget/line.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/line.em_ex2.png similarity index 100% rename from third_party/test/golden_widget/line.em_ex2.png rename to third_party/packages/flutter_svg/test/golden_widget/line.em_ex2.png diff --git a/third_party/test/golden_widget/rect.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex.png similarity index 100% rename from third_party/test/golden_widget/rect.em_ex.png rename to third_party/packages/flutter_svg/test/golden_widget/rect.em_ex.png diff --git a/third_party/test/golden_widget/rect.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex2.png similarity index 100% rename from third_party/test/golden_widget/rect.em_ex2.png rename to third_party/packages/flutter_svg/test/golden_widget/rect.em_ex2.png diff --git a/third_party/test/golden_widget/stick_figure.withclipping.png b/third_party/packages/flutter_svg/test/golden_widget/stick_figure.withclipping.png similarity index 100% rename from third_party/test/golden_widget/stick_figure.withclipping.png rename to third_party/packages/flutter_svg/test/golden_widget/stick_figure.withclipping.png diff --git a/third_party/packages/flutter_svg/test/golden_widget/text_color_filter.png b/third_party/packages/flutter_svg/test/golden_widget/text_color_filter.png new file mode 100644 index 0000000000000000000000000000000000000000..f7f4360c7c53b47c2192a646c459fe7ba7d38845 GIT binary patch literal 2396 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI zLpXq-h9jkefq|3F)5S5QV$Rz;8*_yNMA|N9a|c$lh;|VJQL@M zE-(%9XDo-{_*o0AHOPn?q%k)XL-*Gzw$Bc zD7$@?nSr6V0f@cF0F61`JBs_&z!w`=J6}p z1NUzN-NeAKM~;bwf#C#)00V=9GSs~c3`V1ZzyLu3|9-HpcqZv`_Vhy)khrI-pUXO@ GgeCwFGScn< literal 0 HcmV?d00001 diff --git a/third_party/test/golden_widget/two_of_same.png b/third_party/packages/flutter_svg/test/golden_widget/two_of_same.png similarity index 100% rename from third_party/test/golden_widget/two_of_same.png rename to third_party/packages/flutter_svg/test/golden_widget/two_of_same.png diff --git a/third_party/test/loaders_test.dart b/third_party/packages/flutter_svg/test/loaders_test.dart similarity index 100% rename from third_party/test/loaders_test.dart rename to third_party/packages/flutter_svg/test/loaders_test.dart diff --git a/third_party/test/no_width_height_test.dart b/third_party/packages/flutter_svg/test/no_width_height_test.dart similarity index 100% rename from third_party/test/no_width_height_test.dart rename to third_party/packages/flutter_svg/test/no_width_height_test.dart diff --git a/third_party/test/widget_svg_test.dart b/third_party/packages/flutter_svg/test/widget_svg_test.dart similarity index 100% rename from third_party/test/widget_svg_test.dart rename to third_party/packages/flutter_svg/test/widget_svg_test.dart diff --git a/third_party/packages/flutter_svg_test/README.md b/third_party/packages/flutter_svg_test/README.md new file mode 100644 index 000000000000..3a1e3e2dd91e --- /dev/null +++ b/third_party/packages/flutter_svg_test/README.md @@ -0,0 +1,44 @@ +# flutter_svg_test + +### Testing + +This package provides a set of functions to find images generated by +[**flutter_svg** ](https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg) +in widget tests. + +The methods find elements with the `SvgPicture` type and compare either the `BytesLoader` or the +configuration of the `BytesLoader` with the giving test attribute. + +### Example + +#### Find by BytesLoader + +The following example shows how you can find svgs with the matching `SvgAssetLoader`. + + ```dart +testWidgets('Finds svg', (WidgetTester widgetTester) async { + + final SvgPicture asset = SvgPicture.asset('/test/path/my.svg'); + + await widgetTester.pumpWidget(asset); + + expect(find.svg(asset.bytesLoader), findsOneWidget); +}); +``` + +#### Find by svg path + +Sometimes it is more convenient instead of instantiate the whole `BytesLoader` to +compare only specific attributes. + +The following example shows how you can find svgs with the specified attribute. + + ```dart +testWidgets('asset svg with path', (WidgetTester widgetTester) async { + const String svgPath = 'test/flutter_logo.svg'; + + await widgetTester.pumpWidget(SvgPicture.asset(svgPath)); + + expect(find.svgAssetWithPath(svgPath), findsOneWidget); +}); + ``` diff --git a/third_party/packages/flutter_svg_test/lib/flutter_svg_test.dart b/third_party/packages/flutter_svg_test/lib/flutter_svg_test.dart new file mode 100644 index 000000000000..a2200ef51114 --- /dev/null +++ b/third_party/packages/flutter_svg_test/lib/flutter_svg_test.dart @@ -0,0 +1,170 @@ +import 'dart:typed_data'; + +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:flutter_test/flutter_test.dart'; + +/// Extension on common finder to have native feeling +extension CommonFinderExt on CommonFinders { + /// Finds [SvgPicture] widgets containing `svg` equal to the `svg` argument. + /// + /// ## Sample code + /// ```dart + /// expect(find.svg(SvgPicture.asset('assets/asset_name.svg')), findsOneWidget); + /// ``` + /// + /// If the `skipOffstage` argument is true (the default), then this skips + /// nodes that are [Offstage] or that are from inactive [Route]s. + Finder svg(BytesLoader svg, {bool skipOffstage = true}) { + return _SvgFinder(svg, skipOffstage: skipOffstage); + } + + /// Finds widgets created by [SvgPicture.asset] with the [path] argument. + /// ## Sample code + /// ```dart + /// expect(svgAssetWithPath('assets/asset_name.svg'), findsOneWidget); + /// ``` + /// This will match [SvgPicture.asset] with the [path] 'assets/asset_name.svg'. + /// If the `skipOffstage` argument is true (the default), then this skips + /// nodes that are [Offstage] or that are from inactive [Route]s. + Finder svgAssetWithPath(String path, {bool skipOffstage = true}) { + return _SvgAssetWithPathFinder(svgPath: path, skipOffstage: skipOffstage); + } + + /// Finds widgets created by [SvgPicture.network] with the [url] argument. + /// ## Sample code + /// ```dart + /// expect(find.svgNetworkWithUrl('https://svg.dart'), findsOneWidget); + /// ``` + /// This will match [SvgPicture.network] with the [url] https://svg.dart'. + /// If the `skipOffstage` argument is true (the default), then this skips + /// nodes that are [Offstage] or that are from inactive [Route]s. + Finder svgNetworkWithUrl(String url, {bool skipOffstage = true}) { + return _SvgNetworkWithUrlFinder(url: url, skipOffstage: skipOffstage); + } + + /// Finds widgets created by [SvgPicture.memory] with the [bytes] argument. + /// ## Sample code + /// ```dart + /// const Uint8List svgBytes = [1, 2, 3, 4]; + /// expect(find.svgMemoryWithBytes(svgBytes), findsOneWidget); + /// ``` + /// This will match [SvgPicture.memory] with the [bytes] [1,2,3,4]. + /// If the `skipOffstage` argument is true (the default), then this skips + /// nodes that are [Offstage] or that are from inactive [Route]s. + Finder svgMemoryWithBytes(Uint8List bytes, {bool skipOffstage = true}) { + return _SvgMemoryWithBytesFinder(bytes: bytes, skipOffstage: skipOffstage); + } + + /// Finds widgets created by [SvgPicture.file] with the [path] argument. + /// ## Sample code + /// ```dart + /// expect(find.svgFileWithPath('test/flutter_logo.svg'), findsOneWidget); + /// ``` + /// This will match [SvgPicture.file] with the [path] 'test/flutter_logo.svg'. + /// If the `skipOffstage` argument is true (the default), then this skips + /// nodes that are [Offstage] or that are from inactive [Route]s. + Finder svgFileWithPath(String path, {bool skipOffstage = true}) { + return _SvgFileWithPathFinder(path: path, skipOffstage: skipOffstage); + } +} + +class _SvgFinder extends MatchFinder { + _SvgFinder(this._svg, {super.skipOffstage}); + + final BytesLoader _svg; + + @override + String get description => "svg: '$_svg'"; + + @override + bool matches(Element candidate) { + return _getBytesLoader( + candidate, + (BytesLoader loader) => loader == _svg, + ); + } +} + +class _SvgAssetWithPathFinder extends MatchFinder { + _SvgAssetWithPathFinder({required String svgPath, super.skipOffstage}) + : _svgPath = svgPath; + final String _svgPath; + + @override + String get description => "Path: '$_svgPath' and created by SvgPicture.asset"; + + @override + bool matches(Element candidate) { + return _getBytesLoader( + candidate, + (SvgAssetLoader loader) => loader.assetName == _svgPath, + ); + } +} + +class _SvgNetworkWithUrlFinder extends MatchFinder { + _SvgNetworkWithUrlFinder({required String url, super.skipOffstage}) + : _url = url; + final String _url; + + @override + String get description => "Url: '$_url' and created by SvgPicture.network"; + + @override + bool matches(Element candidate) { + return _getBytesLoader( + candidate, + (SvgNetworkLoader loader) => loader.url == _url, + ); + } +} + +class _SvgFileWithPathFinder extends MatchFinder { + _SvgFileWithPathFinder({required String path, super.skipOffstage}) + : _path = path; + final String _path; + + @override + String get description => "Path: '$_path' and created by SvgPicture.file"; + + @override + bool matches(Element candidate) { + return _getBytesLoader( + candidate, + (SvgFileLoader loader) => loader.file.path == _path, + ); + } +} + +class _SvgMemoryWithBytesFinder extends MatchFinder { + _SvgMemoryWithBytesFinder({required Uint8List bytes, super.skipOffstage}) + : _bytes = bytes; + final Uint8List _bytes; + + @override + String get description => "Bytes: '$_bytes' and created by SvgPicture.memory"; + + @override + bool matches(Element candidate) { + return _getBytesLoader( + candidate, + (SvgBytesLoader loader) => loader.bytes == _bytes, + ); + } +} + +bool _getBytesLoader( + Element candidate, + bool Function(T loader) matcher, +) { + bool result = false; + final Widget widget = candidate.widget; + if (widget is SvgPicture) { + final BytesLoader bytesLoader = widget.bytesLoader; + if (bytesLoader is T) { + result = matcher(bytesLoader as T); + } + } + return result; +} diff --git a/third_party/packages/flutter_svg_test/pubspec.yaml b/third_party/packages/flutter_svg_test/pubspec.yaml new file mode 100644 index 000000000000..42877752fcf6 --- /dev/null +++ b/third_party/packages/flutter_svg_test/pubspec.yaml @@ -0,0 +1,18 @@ +name: flutter_svg_test +description: A testing library which makes it easy to test flutter svg . Built to be used with the flutter svg package. +repository: https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg_test +issue_tracker: https://github.com/dnfield/flutter_svg/issues +version: 1.0.0 + +dependencies: + flutter: + sdk: flutter + flutter_svg: ^2.0.4 + flutter_test: + sdk: flutter + +environment: + sdk: '>=2.19.0-0 <4.0.0' + flutter: ">=3.7.0-0" + + diff --git a/third_party/packages/flutter_svg_test/test/flutter_logo.svg b/third_party/packages/flutter_svg_test/test/flutter_logo.svg new file mode 100644 index 000000000000..ec3d9144f352 --- /dev/null +++ b/third_party/packages/flutter_svg_test/test/flutter_logo.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart b/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart new file mode 100644 index 000000000000..a3a88e05f954 --- /dev/null +++ b/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart @@ -0,0 +1,183 @@ +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_svg_test/flutter_svg_test.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('finds', () { + group('with bytesLoader', () { + testWidgets('asset svg', (WidgetTester widgetTester) async { + final SvgPicture asset = SvgPicture.asset('test/flutter_logo.svg'); + await widgetTester.pumpWidget( + DefaultAssetBundle( + bundle: _FakeAssetBundle(), + child: asset, + ), + ); + + expect(find.svg(asset.bytesLoader), findsOneWidget); + }); + + testWidgets('network svg', (WidgetTester widgetTester) async { + await HttpOverrides.runZoned(() async { + final SvgPicture asset = SvgPicture.network('svg.dart'); + await widgetTester.pumpWidget(asset); + + expect(find.svg(asset.bytesLoader), findsOneWidget); + }, createHttpClient: (SecurityContext? c) => _setupFakeClient); + }); + + testWidgets('string svg', (WidgetTester widgetTester) async { + final SvgPicture asset = SvgPicture.string(_svgStr); + await widgetTester.pumpWidget(asset); + + expect(find.svg(asset.bytesLoader), findsOneWidget); + }); + + testWidgets('file svg', (WidgetTester widgetTester) async { + final File file = File('test/flutter_logo.svg'); + final SvgPicture asset = SvgPicture.file(file); + await widgetTester.pumpWidget(asset); + + expect(find.svg(asset.bytesLoader), findsOneWidget); + }); + + testWidgets('memory svg', (WidgetTester widgetTester) async { + final SvgPicture asset = SvgPicture.memory(_svgBytes); + await widgetTester.pumpWidget(asset); + + expect(find.svg(asset.bytesLoader), findsOneWidget); + }); + }); + + testWidgets('asset svg with path', (WidgetTester widgetTester) async { + const String svgPath = 'test/flutter_logo.svg'; + await widgetTester.pumpWidget( + DefaultAssetBundle( + bundle: _FakeAssetBundle(), + child: SvgPicture.asset(svgPath), + ), + ); + + expect(find.svgAssetWithPath(svgPath), findsOneWidget); + }); + + testWidgets('network svg with url', (WidgetTester widgetTester) async { + await HttpOverrides.runZoned(() async { + const String svgUri = 'svg.dart'; + await widgetTester.pumpWidget(SvgPicture.network(svgUri)); + + expect(find.svgNetworkWithUrl(svgUri), findsOneWidget); + }, createHttpClient: (SecurityContext? c) => _setupFakeClient); + }); + + testWidgets('file svg wit path', (WidgetTester widgetTester) async { + const String svgPath = 'test/flutter_logo.svg'; + + await widgetTester.pumpWidget(SvgPicture.file(File(svgPath))); + + expect(find.svgFileWithPath(svgPath), findsOneWidget); + }); + + testWidgets('memory svg with bytes', (WidgetTester widgetTester) async { + final Uint8List svgBytes = _svgBytes; + await widgetTester.pumpWidget(SvgPicture.memory(svgBytes)); + + expect(find.svgMemoryWithBytes(svgBytes), findsOneWidget); + }); + }); +} + +HttpClient get _setupFakeClient { + final _FakeHttpClientResponse fakeResponse = _FakeHttpClientResponse(); + final _FakeHttpClientRequest fakeRequest = + _FakeHttpClientRequest(fakeResponse); + return _FakeHttpClient(fakeRequest); +} + +class _FakeAssetBundle extends Fake implements AssetBundle { + @override + Future loadString(String key, {bool cache = true}) async { + return _svgStr; + } + + @override + Future load(String key) async { + return Uint8List.fromList(utf8.encode(_svgStr)).buffer.asByteData(); + } +} + +class _FakeHttpClient extends Fake implements HttpClient { + _FakeHttpClient(this.request); + + _FakeHttpClientRequest request; + + @override + Future getUrl(Uri url) async => request; +} + +class _FakeHttpHeaders extends Fake implements HttpHeaders { + final Map values = {}; + + @override + void add(String name, Object value, {bool preserveHeaderCase = false}) { + values[name] = value.toString(); + } + + @override + List? operator [](String key) { + return [values[key]!]; + } +} + +class _FakeHttpClientRequest extends Fake implements HttpClientRequest { + _FakeHttpClientRequest(this.response); + + _FakeHttpClientResponse response; + + @override + final HttpHeaders headers = _FakeHttpHeaders(); + + @override + Future close() async => response; +} + +class _FakeHttpClientResponse extends Fake implements HttpClientResponse { + @override + int statusCode = 200; + + @override + int contentLength = _svgStr.length; + + @override + HttpClientResponseCompressionState get compressionState => + HttpClientResponseCompressionState.notCompressed; + + @override + StreamSubscription> listen( + void Function(List event)? onData, { + Function? onError, + void Function()? onDone, + bool? cancelOnError, + }) { + return Stream.fromIterable([_svgBytes]).listen( + onData, + onDone: onDone, + onError: onError, + cancelOnError: cancelOnError, + ); + } +} + +final Uint8List _svgBytes = utf8.encode(_svgStr) as Uint8List; + +const String _svgStr = ''' + + + +'''; From c841da48983cfddb189e2261225dc6a27828c7ab Mon Sep 17 00:00:00 2001 From: Dan Field Date: Wed, 19 Apr 2023 15:20:10 -0700 Subject: [PATCH 490/512] Update README.md --- third_party/packages/flutter_svg/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/third_party/packages/flutter_svg/README.md b/third_party/packages/flutter_svg/README.md index 9ac9beb906f2..64aa45bcdffb 100644 --- a/third_party/packages/flutter_svg/README.md +++ b/third_party/packages/flutter_svg/README.md @@ -78,8 +78,6 @@ package, this package _does not render the data to an `Image` at any point_. This carries a performance penalty for some common use cases, but also allows for more flexibility around scaling. -See [main.dart](/../master/example/lib/main.dart) for a complete sample. - ## Precompiling and Optimizing SVGs The vector_graphics backend supports SVG compilation which produces a binary From 85292f14e80ba397324146031b06fa61c56a6ca1 Mon Sep 17 00:00:00 2001 From: Jason Simmons Date: Thu, 20 Apr 2023 09:58:37 -0700 Subject: [PATCH 491/512] Update test golden images for the latest Skia roll (#908) --- .../text_color_filter_isolatedDiff.png | Bin 2247 -> 0 bytes .../failures/text_color_filter_maskedDiff.png | Bin 2421 -> 0 bytes .../text_color_filter_masterImage.png | Bin 2396 -> 0 bytes .../failures/text_color_filter_testImage.png | Bin 2429 -> 0 bytes .../test/golden_widget/circle.em_ex.png | Bin 10224 -> 14207 bytes .../test/golden_widget/circle.em_ex2.png | Bin 10224 -> 14207 bytes .../test/golden_widget/columns_and_rows.png | Bin 25790 -> 32678 bytes .../test/golden_widget/ellipse.em_ex.png | Bin 6534 -> 8367 bytes .../test/golden_widget/ellipse.em_ex2.png | Bin 6534 -> 8367 bytes .../test/golden_widget/flutter_logo.asset.png | Bin 10275 -> 10864 bytes .../golden_widget/flutter_logo.memory.png | Bin 10275 -> 10864 bytes .../golden_widget/flutter_logo.natural.png | Bin 25928 -> 26474 bytes .../golden_widget/flutter_logo.network.png | Bin 10275 -> 10864 bytes ...go.string.color_filter.blendmode_color.png | Bin 9344 -> 9676 bytes .../flutter_logo.string.color_filter.png | Bin 7599 -> 8160 bytes .../golden_widget/flutter_logo.string.ltr.png | Bin 3389 -> 3722 bytes .../golden_widget/flutter_logo.string.png | Bin 10275 -> 10864 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 3389 -> 3721 bytes .../test/golden_widget/rect.em_ex.png | Bin 4070 -> 4626 bytes .../test/golden_widget/rect.em_ex2.png | Bin 4070 -> 4626 bytes .../stick_figure.withclipping.png | Bin 20024 -> 20756 bytes 21 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 third_party/packages/flutter_svg/test/failures/text_color_filter_isolatedDiff.png delete mode 100644 third_party/packages/flutter_svg/test/failures/text_color_filter_maskedDiff.png delete mode 100644 third_party/packages/flutter_svg/test/failures/text_color_filter_masterImage.png delete mode 100644 third_party/packages/flutter_svg/test/failures/text_color_filter_testImage.png diff --git a/third_party/packages/flutter_svg/test/failures/text_color_filter_isolatedDiff.png b/third_party/packages/flutter_svg/test/failures/text_color_filter_isolatedDiff.png deleted file mode 100644 index a7b0e37514ac83ab1041e907949218f5592541ad..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2247 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzEX7WqAsj$Z!;#X#z`#-G z>EaktG3V`dN8UpW0t}8$6PkN=tzU7NY5qG_tHlZXe^&rC4OK8<*39o^%nWx97Fz?o zu!EnOiGd-7hl7D(f}sKfgTt`~ps3`iASgg8bJ-d8C#LniZR?(Un-Lf;qhK@yMnhmU z1V%#udk7q;p8={|KJ0y722@ZW&&I;Qa6&?Wfk7eJfq|i+hY?ta8jT8q0_5{8J_d$$ lrpCw14j(=D77?5c2iVOH^844-30wdPdb;|#taD0e0swHXiqrrA diff --git a/third_party/packages/flutter_svg/test/failures/text_color_filter_maskedDiff.png b/third_party/packages/flutter_svg/test/failures/text_color_filter_maskedDiff.png deleted file mode 100644 index 29981f0358e7ef49b05257510617b9e30bfcc942..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2421 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzEX7WqAsj$Z!;#X#z`&{F z>EaktG3V`_y}45zMO-ghiz$_Hnj~}zITXov9NFlts9L1`WXY2)4Z*@SDlKC6LizoF zBUU#}&Wk;J258(61tr(sF&_B*q43#_y$`44^*zp7`!)4DAA?1?_-=Nfm;UoJGBGfu zuy8OiOb}FHU~q720E$YE3W5S85*S414;RW@-)%nU#`CS${=O3g2F@rL4S~@R7!83T z6#{>jZmniuun8?Uo_;_5o~&{HwKGrO+5Wk8_RQ_O(hc{kH-cncfwKI@@z2vMWM+S7 znA6>Tmzm*#X4Q$n-cjfOH zEX?Z;GBvpGng6rQ{PU~CXJu#i*x7i1DjTYT2IFmI{0t0!uOFY;SbbRYuFUbPQLj(G zlRYqh=M7t+O+V^61Q-|;lpPot8hRKQ85oS1SQr>ij0%DRH_kHU?f}XB^F6*2UngHI{-(LU# diff --git a/third_party/packages/flutter_svg/test/failures/text_color_filter_masterImage.png b/third_party/packages/flutter_svg/test/failures/text_color_filter_masterImage.png deleted file mode 100644 index f7f4360c7c53b47c2192a646c459fe7ba7d38845..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2396 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI zLpXq-h9jkefq|3F)5S5QV$Rz;8*_yNMA|N9a|c$lh;|VJQL@M zE-(%9XDo-{_*o0AHOPn?q%k)XL-*Gzw$Bc zD7$@?nSr6V0f@cF0F61`JBs_&z!w`=J6}p z1NUzN-NeAKM~;bwf#C#)00V=9GSs~c3`V1ZzyLu3|9-HpcqZv`_Vhy)khrI-pUXO@ GgeCwFGScn< diff --git a/third_party/packages/flutter_svg/test/failures/text_color_filter_testImage.png b/third_party/packages/flutter_svg/test/failures/text_color_filter_testImage.png deleted file mode 100644 index 20ea01b6daa35ee9087c6fea46d2b9302001805e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2429 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI zLpXq-h9jkefq_%q)5S5QV$Rz;hJI55CE6~&XHPmS6w%~;ps7?sIO%Lq&dN0HcSklb z=NP8s=%{D)e2$Sg7kTiu-Or-;JV4`yCU8iPwq>Z0eV6`iwYkjYpJ%SVJ#+Y#EJMMo zb7A~IAKl|)WMW`QVc}q4m>{UYz~JE402GxR6$Ayy&InM@ZJRm!s&wDW%4daNK`Ct% zjE2By2#kinkP3l+2e(x*FzgB0J@d4@vHW-A>$lH5eP#RS-t(FKtIZke%Qk{!U4XL7 zXXby_w)ximoncPb=BvyM4^*pW?UWAZZ}{)mz;Gb(`f7HDIZCkFLFQZOSB8dQ6$gd~ z4dur1Y0rKGYnJ85^dlGw4lJK}{O*~nm(Sca`&{?l(TeJ!HD^QaR|bX$JJ2e&1NSX~ u^&JC4h4pBarhuzDf0hIeI;<62!vTNqBhs5H|K;2S#hIt8pUXO@geCwpCE_{& diff --git a/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex.png index 9c72bdcbea280fda4aa3b156426e9245db3ad49d..ac9af33da57ca012b93e930391076a29ae6dfd2f 100644 GIT binary patch literal 14207 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 literal 10224 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 MgYEh|7Tk#c1$ZGXHvj+t diff --git a/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex2.png index 9c72bdcbea280fda4aa3b156426e9245db3ad49d..ac9af33da57ca012b93e930391076a29ae6dfd2f 100644 GIT binary patch literal 14207 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 literal 10224 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 MgYEh|7Tk#c1$ZGXHvj+t diff --git a/third_party/packages/flutter_svg/test/golden_widget/columns_and_rows.png b/third_party/packages/flutter_svg/test/golden_widget/columns_and_rows.png index 105dbecb54686478846c83fdfa7c9d51bbd730ef..acd19c0a4a3f21f38fdb52601ec44f9b4831a607 100644 GIT binary patch literal 32678 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 literal 25790 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 diff --git a/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex.png index 3244264aae23833ef7e318faa5d6951c95bbae3a..e3a3a585e8fb38fb84930d38fdee2a938602e45e 100644 GIT binary patch literal 8367 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 literal 6534 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 diff --git a/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex2.png index 3244264aae23833ef7e318faa5d6951c95bbae3a..e3a3a585e8fb38fb84930d38fdee2a938602e45e 100644 GIT binary patch literal 8367 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 literal 6534 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 diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.asset.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.asset.png index c73024a3e8466eac6de9e2e133e3787c6dd8fac6..d2fe2c73b96cc05babc542a9c04ef76f8d23345c 100644 GIT binary patch literal 10864 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 Q_M)n6tsL0}ERWOw2fap}6#xJL literal 10275 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 Q_M)n6tsL0}ERWOw2fap}6#xJL literal 10275 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 literal 25928 zcmeI5iC@fH{Qp0=$lkPx78zQ!5LZQM!L&%SPBW-xvR7!Lg^U^sEm!3mt}S&7F_UIo zy0SD)ku2A)ETL|;lrR#LRNwPC@6UYd-v8kD{pE2VSNHun=Y5{%b>8QFme0qPG|$&_ z$iR^U34$0h%Zs&uAO`RWqQ8blKV&JY{P7F=t=Gl{o->GoJBIJkfBdp>#;ipe=$BAq zMIu3%5VKg*7i~K7p|n>o^i-7IA^oU9dh7Ysqd<=WJqq+F(4#<)0zC@!DA1!oj{-dk z^eE7yK#v0drxg%Ay^wMEc0upt9O;UFUWt>BBxblBoBqpC5pi9yF)iGLRhM+j$NP9l z$J@}rv!9AX-37g$IR2kjq^EN|3iK$@qd<=W|34{kwoTB2`^zn#Tk^Bx)whaKofl*J zU#{OZs-wLo?q^FJ=Pr6Ky8rV{19^E)$hK$2wzgNKjdJaHcjd44_6D2JnZv5@mLy5h z!`jitGO|!DKkJpmwNr<8zd5L_^?Y1M(__hMWLKR0g-bpcm?(9F>#WdEn+_3!NXt;B zoH<9>7yWcelTS9J=yjEI3_ImJ^tL98JUOUJo~+bGKYj2PktGQyE#4k8d2fXGVgPQJ zZ(e8h;3@|_5@__&Ba3`+6S^N#k(d2L$0$%qLS&vK_0r~{CKP`F%;#U!FjI~IjPY1C zOdbW(M-5Xu8DNSs)G$XVm}pHk%tL^w^`Kz}0L*h5W;_KGov4O6PQmn3!xT|4fuq$h z1EA?m+tf|3&;Yd!)D5LGp^p>PZrxI$M=lIC+*m+aTW3{=g-SQYRrs4}A7)@c;{#Hr zn}cDo+F<(&_?S)09|R!WR5jUPcRWIh1!~>+QviNH-J6+Oc${Ul`uh7ZtLQyFK=(is zpE>F=+)1Gch7yFuMyg#l>d@2z&b zX&1P?r4B#B0p^cj0Ns!WG~{cphI>98Lgf_Qv=hvqDZACt^qGKB&ZA+B#{!IihS3HX z!!DTr0hlW^j1vW;p@!j`156YR^T7*X3TT*2fO$g02q>6KG|W(tx0aqUifsTh&0Vd` zlmh^>OC3;zIlz3@RKwJc1(=U!YGsa4Fab172EY{2nNZLRlyOkcZ(=+J6F@7o17I%C zQo|HcFdQ1D7c?D6=RFpTzKRZAP0Fp6+O6Af(4)IFoC%;*|CJ<7#0i#|4{on=&f!EZ zvc)A7DDgmM7fk^}8ExnV?ds8?J9q{j5E;E-@J+B&Q8_)V@eCa9)+}}Z^wTjKpP^<| zWP=2Q=ppL|N$$WAb%@zgC|7Be0f1sgqxb-d?P&Fg@tJ^fgGR{!6dxMp0EMDOqZ|Vi zZ5qW4Q1rV{rh+O88l^9w^rKO%DU>c%MgvMIjgkT=gJ~2lg`!ELI2?1PZ?q+u=r z%!e)*O&DS$8phBAOZ|B)4Kou|I%=X8UqFR*JPqRuFq^tyf&nI)9>OUAQ#+J~$pe_@ zUg{}Us|7FyG>kt5Gn9sz4KOdeV5q>hqG7b4=?QcMUWWh^&Qv#K0!!v+dTACJg1q!j zkC+80Xk|WvH+m+su`JeeX&-aIK(E~h3% z0Pq9o-du((>hG%#1Caxs%%a(}CZC6562S=d2omc}@XljAy<=1Ch91AC;fmsMs7%>M zHysTLE|1o&7FOI^9U5jDEcS+7Fy;U=vkM0H?gD)pCJJDNcER`p%tspL$sP>zqzlFg zCiA5(7y?3WI1OV6@=l{?jHnMpOCBw_02cGlbS5Nx0mis%2xbAy3mRq$z!as>%9sO; z1Dy$Ldt;bdGaAMpU@p^fDH;SY4zx0YiFlYkThhw(hNe^KrW0ZGYv^8^fLkHGM-%CT z6MAz+Ob1=6?UlOW__RvEl8JIBGNCnu2*M?}^x92?gW&+(!9KWMMOWzRC*T3mqZbT? z8)lVt4QoGqIuz}o#kPgLmGuldQm11H_`PVA2E)pfK?}(jV3Y%0DB6H>jMn4;pqO=` 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 diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.network.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.network.png index c73024a3e8466eac6de9e2e133e3787c6dd8fac6..d2fe2c73b96cc05babc542a9c04ef76f8d23345c 100644 GIT binary patch literal 10864 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 Q_M)n6tsL0}ERWOw2fap}6#xJL literal 10275 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 Ii~aWf510q&ApigX literal 9344 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 diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.png index 3138a2bce82d2bc1ee3f5d9ee18a916f05b20d9a..532d4f1e46e5e981f636a3550a41ee353c5dcc67 100644 GIT binary patch literal 8160 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 bLHA#~6qjawu~(cTXIyEb64l34+AaSJI=J9p literal 7599 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 Ef3wSbq5uE@ diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.ltr.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.ltr.png index 13f1aa453c9e6c1030dcc2927330ce88ca28175b..962179bceb31c8941d19bfe5f8afa2e8f298c991 100644 GIT binary patch literal 3722 zcmeHI2~$(a7VaBRBQ6j?6ylJOuu4jF5Mfx7h=H)o1dM_(Do~0KWyVpA$`&vxG68{r zvdE5r%R>zswh;#5y%8cJAS$42BMP!hMZknbc_-HVi)YuZx^=$(&gs+N={_Cj$ziWi z(^EqTt#Nf>aS>7>BZTw8F9#&+%=r`W!+2b_BNDf690fy_=jgfz4}*^n6e6^Cn=5O_ zp0J$BzI_S%Pk&c0`#baXFMBs%U(QM(Yr2`nJakz(AMo#(VixJgS1ZodU&>$|d=%g) z+}iPIpX2$I^>HbthuxpknXDJ&YXW0qx{Dr#wNl6J*Q#Kn=gsMTxtVq96RGKyJrD9; zTMkc$_vZ4V>!P~((+o>343haazA5m3t^o7?;o;to`}EL z(AUT?<|eC{jau)%5mb>`wP^ki$Za(g~qJXC&6t%Z|`S)Ap*5-ms#M6~{l&kB> zx2MvPS_>G*YK}#g=;vfEh!v>d08Uj<*<0!0wNw)}A@$WE^7PE;C|1b6hmQDK(kYjL zLj_K{P#s0=5TFy@Z&d_-1Tvzz^U*VRn6cC(p_wd%y(xdR0(~YkkbtI>KIO-09A0R1%u!bu1Q8l#&q;J8)2qqGOV7A*AQqz%+>J#=qiDg z05mz!xe-6{(FqEM^VGZ`6v?hGWhu}b7KBkrjl)NthOltG5`ge(ZU87V5h#J7Lt&WO4O5xy!QI~( z*_+bL7b-gAxWyN(igx#$`7vl!_*0bv9*~*wnj~Vr&HP1Y>O-x$oN^0RQAj?Nak(e} z(`Kc-r8Zm9$K;dM)4hzLEvp3j8f3K0^Qt0j@s%-b>!ecPabvoqQGF-uX*I}#N;#$b zu6`Fe-A`-CU$DKkpt$wvXqi@=x&WsIzU^{66l9PoK-w-#6vJ8?h<*VyzWT2iR$!a_ zebVSqXwt^&n|+Euj*ed=HmpFCpxCmRv6*Vf{fa!4WH8kr^?x|u{@{$bT1hG5Ms0x| zA5+pQ4%yxgU2kweD)kBC^-$mpB|z+Zt<>T&#jEnk$1T362Tjc8ZXH0jO2x#V@uT*1 z?vp%@S(I@z<TV8rZA^i_atT!p6XSN^u@{2$Nx3a#Zp4 z$u^NOGc~9*!@eXn4M&7|Aa4z*7OQomL2Z)g#zZ%*p+w(F z2+Cpr2XYdVqZ_2p`>1!PcEkwP1(!kBokygny#GGEP;xxTcd;;E*8cLaa!ONIcLs-M z+Iaq15ygGKbSH{#$SHjWJz5Io? zrD!r8L4HP7A^n3Ngo>R@CRV|bXRR&o4_k|(md>wX*i|h}BcCQ!JkxcuH>X8Z>Nh(l z468i5Td$(FE_ZGr<#XBirXsB_FK-X~g#nMHk2zmjR06KUc`)ki!n-DRXL~rz&$oYG z==5?nDIydRQpBbCSEA4M-?h9QNmmy*Dp&8yP%?=gUlvKc6`%am5;-g?F;V;VbBi)! zp?9QT3`&J-UQk82tXJV+r{8aBZCA6Mn3h1Oqe#*V*Q-H^uOJ#4-6_@(*^lHFC)vTOG68jSI(Z+6w(L z6Xu?ThtTX8I)^BF&5J!sA7zg#8lo6>tRD_#EVe}P%8u{P@{*===q0;I4h$VBe8zOb zbcfZhw#I#VCXOgJA7KH$H!mgc@y|IsdaaaXUwyXiy6-krgY z8thfPVNX?-=o;+Kt~~Ivh=B>#K_ffiZQ|@wV$oVR^CEI>E9t-=ffH|u2Pfh!oX-rz z3Y$c%z>d79?u2o3>LrVK4Z#51up_RPj$b~#eCJ_(L;N7{tt7ihGGF47c0W3Czd0l% zf_fdcvksarJ5Ktu?ECQlh@H20K9TcJxyPW@pfNMj@72c-b{(PCH&Y!lU$6*pp`hbT z_RJ;D{k4jepQKHJhXdX>+v)!{X5q1~4@qmB2I^KmQAq%-fm(k6;AbU}h&er;%MRMy za#SBVfPN#n&~!feaJ0HQ$E~2~`Zm5P@J#_w;9234ieOfI?;?(PP$`J3 L6Ne>s3^@NkGXavB literal 3389 zcmeH|`(Mj@9LGOfIZY3=ZzQK=tJO*&UF6!DS*?pQ^e9BA)I;t`7nLSqlUX&CqN0Nw zq;W(F9W+}~nx%^rl}jmEt-EyI-+ny*0^eV@@ALEeyf3fMh`5gQ2at@2guU=X*uRFuLiv?5+u=oXKg-RV1Wzm}h>y^u&u;AH-cjef-c==? z*D`vp>b6^2eCOS+3IoZdOU?ngHK7^_IZ=GctF?Qwbj_?16n-l5p4|trW!^doU;G=$ zg#nneWvaVac_f~9!{I@2Pp;-g$I}jC&y4U$icZ%JdU5>)N>y*gvZ~&L?~Ydu41bCa zrW2u#-_LIcesKqQVIKX<4%r&@VW{zgu+rl>!?uI=_xtaPj<1-iG_M=Ik2lC=fJu2e z1UNF&TzK&RC`Ltyxitd@c%j46-i3$A+lSAwq^Ut4D^kvdXx9_BSP(UN6-NFWHo3l5 z3&uy@ysRl>6`~m#z6D68{BXJEDBr@C@o22J`_TQhvRP=wR4NK`iA4p51R|6EObb0E zQ_&>PSoF$@KrH0~7{$R#0M-DQ0FD4qgJQk~OxXJdNAb_ z4s@xgQ9OvKJD|W_0v*&tWuiJ3DD**L1d3=-?9`>8HcuWRV=WrI01_Di$D3YY&OjEa zh>&NaA~35pNlZ_O;If>Dl*xl=i#LFmd;o3$_yCl+0)X@|Od+TUrT3v6J%};GoT!=e z1cJ7LpWdfII&&hKrwv(8LbF^O$hwctM3!u5t2LEhpH4fJL6pDnGDwHH==6-p16R6cmy6}kJz1}fpC6GXP%#uq)Uy2X&BNLi`1 zn<710wyOx-DgOTwEmCejx(w`v17P!q5|n z!>dhQ6cgUhX8*9M#lVb85DMB1jA4*Sf0;gLy9+I#sKsCrari{?#THt$gCc5CYMp*G2VBiF zg(;Y$v#dZ>eI^n@^U7hx^lk?x2I)~YMLXjXd)&mgF0OAta$sBnn@ca8lh_85_2ZHW zAXyzEs?2gVnZ92r%HK)@vz0FUm0Bn{+l~{WKQg+qSykQVpLkwm-*l4Sp5+7!7g{!z zj2tG>^FO=}RDz8o%vq>| z!$SqLlSoDC;_U41joah%t9LqQ*e}eEZJaAq=Rg<=e#DLmlKb~$4TXH}IeJ_iY~>Ka z7vj2 zPcMANF>t%VvDlPIPuKWGl2ggvF2&ICRKYb@v7qk9lV}D1u5@K% zXs0k!zOlsc^-_i&W{mpq8=%??yIm4h64#};p6x}y(iGE^VjmdSu|l=`>(qUB`mWt~ zlvuwJ`&9XvXyy!Sl2CEOJl0u#(Y@wJgQ8KlK-+*%ffAd6p>=NuF0adsp8qB@=8q;_ zV^jmD_=|juBkO5V_4m~_H#QFs`UZAf+~d+ynnnv|7^K+S)#Exd(A5{w?)2(=J^uc} zul>k~U-plKrZGC~hV=4n9*M|Xj0ic_w=N70uXQAI&usF?4!@UEK z&d}xDvGgV@jL4k}*W2N6FG{9}FlO^`GgQ3~1PWqoO< xCK6HMckSs2acBJRI|1K|-_LIcet8GfUmnXMJEu?!GMD3CxH)^V^I2OG{sTz&_wxV% diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.png index c73024a3e8466eac6de9e2e133e3787c6dd8fac6..d2fe2c73b96cc05babc542a9c04ef76f8d23345c 100644 GIT binary patch literal 10864 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 Q_M)n6tsL0}ERWOw2fap}6#xJL literal 10275 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 J&@teb{{dcRr>y`0 literal 3389 zcmeH|`(M*#6vxkZkW4UOpn{|^Hg0KZSYZjwIR|5SftT(j-o=~>ge@;|3-B9J4hZFD z$mC{IT!AQ3k|Ihv7^FB%kYPZ|O>kTqg3d9d^X+lx0C-dA&))!G!UUjgrq4hki%k3+e~7~y1Ux9aH-7+MOb_#fB04^Cbg>j*)>9#W zl_)xIs6(BaXSP748+qTWs-ok-U5D}?e(?Q7-V$z-SQITSZ`vp+uyNUDx<=CF)Y(49 zidMXBdcXQ-r-)isipV)2tNH7rWU1%1eWP;IGd|g#S?gp+q8zP;N?ohk@*UOB?|Q4B z$95c3zclp4>~p2zI;Nj#2ma>{kcZY-F1=7J=g>&6>jz)-4+{L^`Ev$ij6GV0u0}Be zkB>UYIcSo?ioh!~+mFQm-!PZ}+}$!9Aj1uH7Rzrqh8c2sb(!McyBWFrE!t=y?le>K z?t-0LclbXTOa6D{VPi`z?+Vzn;aS9CDC{Fu3Vk`2@Olw%i=71&* z2&Qe93AvMQ4d1$Qp#LNgA?^qg5X_)J4gw~ERR|0S?6ZL=T8dydf>;WCkH8JVy9gp( zI8dL0Qv?*iEW^S$NdJ(a)m%}UL5wvMBAif>3dCbeRCuGpGuaA8UAZ8o>j_u>2#VO@0}U<>*ns<-!b&UYk7i8I@A>c;hwupsd{3! zsZis;$EiVER^_7mP7m&87ek0_|1DkYKQ`BEOBZKG_YG#W<(U6zLTzJ_vr^@$G~*87 z+DF~{(p=FJYPG^VpA}!SSg+HyQav#DqmX|n%^C*@9Bk;Zal-NvagNRJAMkK-Z`d%w z<)ko4Y6a%#Y(Rv9&OjqbT-4RCSmGxA=4%{B#>(T;D8r+-vh|>tj}{T}zV$)63~#$I z@A<;P)az_?Rg{SiNeftFjlTbPFAUAyJJXspZ}Z??PB~F_okdAxC^>b2?W{$~3QE#T zNv^SZqbMn*B+ZE^QB(-_2RbuSuht1#FEP;UaQVm2OrTz!E3ZhMOeh}F_s1^f-4i%S z{FF!3g}8CQbj_s0=^4jQlqD2mDdZ!(34Hzx-TjtNsn@Moq}a}JN0l#nqF9U-9L`k< zTC4xfNG+Y|_^4AOrGW+5)>cq+k-Tjk( zhR{dhdA3e4j%Qhu?VGgSFr>a0Rrd4B*3c`gb+XfeoZ;{NVuLWu3F?a7=KD{ys$W+e zes$}%uwu?zUP?i*!@4=g-`o~ko zTQ|LOroLe2hWa|#ZtG&FIX{%ot9-Dj^xU>?K1Ml)Sqfs4(|cTr9%@N zN*lfHwT(U|l4NT#9B=Vh&lFo6ql=y}XeGmvcw>pjc++xr%;P(Z_Z`#xWw{Zkdxi&R zY_L6}?Ulv(UB=oAW4}#a2u$$FtTtmESlfHqg$F-j+iA*aUGMYi$e!5G!q~Zw#?MC{ zqXq;xP+9rf*daM5T-Lm@_+>y6h_IW5F!LX%`u5ZuT|1IPClr?0@M`#Un8Z}Ge3PIF z8+uI>f@S!?27Xz8vmNoH&kYRVA)rF(oeay-lB8 Hki>rg9Qpw3 diff --git a/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex.png index 03519b9cd0df80b88d6465830d6bf3ffb1be145c..78fa8e1206e717fe141cdfd8facdcdc8476769ab 100644 GIT binary patch literal 4626 zcmeHK>t9n>7Ci|Of|Qqb5Je${5L7_Y0)-R;_^2^F9dQJKN~S8Yh@jyont%{+C}l*D z@HR2%V9RtsKwd2pR|3003j^fqjPn(8B?M4#(=lC)blQ&cYii@epMXsOi}{1qYbKJ=DWkc%@)Z zdbR@P0 z0Iu7XwpY=|t%BTt{C2?VbVTS5dt}!@P^kM8Tw{P0m$h5aI~e9VPiEPJvc&FLV z@-_v=Z4s3v#?bFeNUpVE^|B#JcbQ6{BDIqYVM-saKNAD;zWt_PuvT6!>Z^C~s&{Z~ zAq2<@_##eJsUoOqE!sQD9uWr)9SDcE-jiLLJ_ z9Z=6xeaed~WJNAbmq;YmhF3QX%}V#e7dy+Azvc|7St%FqpaUx%m`>z!F;iRB?BbGV zjY;uJh^6If>{{IDi!;Mx4g-*-H%eqk(ymy)551P?TKYbahm(?(rSGR;>}V&q>yDto4S9 zKst&QB6_jRh*F=7aR0UK?>_zd93N zk~@kQX(!2--s&5hVdN#`ETGYpEIGIZ#Z~?>zEwd8j{a zs$9gEUwI3jt=}a%%{=j%?p3!N!mg!8?-Kf32Qiee`nb}nKJ|fihfTR~#Y~WH+&ka> za#s9s;b{$M=JS6#d13XQoI6rci5$WC(d>97rUb22>I$B@c~q}f8}#I7^}g8pI%~0~ zT9H7R2RHphlAj{gGN~&q-_Xp{VCBBR-b-DCm%GE-?T-a6?ma^afyG_vqSTE=&59lD zd_Z%-70xi3g>m`}g`OEORZZZNb&-azR?$J7iBHD5ncjI}rtC(oeaqL7+HWrsD%H(N z^x&&7%&*4S>W-HwxN$w2SF&jOC=hoVW5xgWEj`_@mQZ_a+Saje9TUo;`r}2e6R`wMYhyEM~X zlbrb19+B{38z9R3lazhUF1l~aoY2P%GE!^u-U8a001|g*e;%9Z;74m)_WP+9~h%y2}i+ zL1UDgE=0_ZR!Rt)N${h6mW2fkQ#~f7``E|{6LS!wT-vGwzK=-qqQP1VZuqhQFzSHI zV$A@!nFCM&bba{wfrk%&f)AVF|LO$k!eg7sfSvi z0P4=d$8Z3J28p{4dzm@xWp5&#Kun|UADwKuW6}^fSwavVf@<@u0rJbaBm{%T5Y)OC zmA}XCTd^==Z-$-B7Ire;x$gkc?srH=QZiIIjjqw=RE9}R#*DFM;Q^veln_AMtyx}~ zG$hVru+@+Mjz$`bd7JAjQ0UXLB1%DZ4j+XK&oCd~Ayt3LMz%b^&kI~El6ryCX-XeD%vw0IJfBsAuS^T$jaNMx2iNK|R2H=}gX3ZLH>TvPm3aRCr7_}pjh2cfWA zUnv?cQYfL=ms+{h@{N%~3|4$|TW8|bYL_8cQ@K1(_x6AbLj`DfUS`_SfCE3Tu+KwI zE0PlVfs2*8Xv37@RAd%b+%c81UFcdt2SoA0lLn|UApQKQ3loPqZ?3|0iR}$63*Z`C zVSw1qWT{VataKJ&K-$bJ-vTwd$jZ#qW1hM=K4}gLwe!60Z50&6b|dbr$#VujSo8q$ zw7tGinZ%`o7g1Ol4Yv zXIQ9V6};}&{>56DT-}TN#jeb!lje1Q`x%vPJYdtMJSz0Xx5Pr@@%f|Bqg^4*k&CmF zpZqZ$FKm$Ims7VM29ZbuHU49py1P1GrYm0*M9t09nYK%=&b}kX>H!FP@)m0m$5}mC z)9G&=z<3SqmslaxM9G&_Txd>?DD*L(Q(Nsj)Dfw+!Z2v+Xt8UBUui#GKyfK-gb-_x zXj?mR4^Pp}1m#V9FKC++8R>u%cHswa+6Z%bLW6=7+$EOk+ecdYP0#pyXtX~TPBpqFlaY>@Lp zA2Z>Xh6}4y{?x~a2D?LtY-H0Pn-sMMKchxrG+pjCerOCiz zScta~)ucQsAI#K#;zu)iZP$XUo!HdJpm40lo7NNW@D+FQZ(_oH`j?bScuq-B1sRK5 zQa$A*iXQxYFk^0v1k}?rRG%A)jqlB-p5Rjy+UT}T7q_8sroX{MIEoL;8O0Dg7aF~b z`S2hkX}ZKr)!=AfpfMKV?Y<=^=`~adUo$H_v~*ilFIfFDDA3Ta}$ebkI-0{F#oJA8LUNJOgV+Ew4J7$gY!O9U;^&gZI_!p=JCJ DuIGS@ delta 1999 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 DuIGS@ delta 1999 zcmYjSdpMNa8eiWxqZuX|=bY$b7@9bT*+^{;k%`#m6xz>oFv>6|O==UGQOc$7F*;^u zNX1 zeC5ubXGoUm+n7D}o4}3x?ELZl3(xzRO70*&k2J0N$>$ zo;M|Z9@ab(g6dz_IN_4FgO;XQ-_n`NC3Ec;wm_5J)qSXTbFXMY~zdr`FOWPPJk{8<|Shsq5>u5i}rN_Dq*KF;hg|ky4m_k08ahUufa%!dor13 zkvwaHmwV$U5?A)`5mEkK8D5M$n1KEr55fhV+Kc zbS>SV0>X7u&JP`JIRI$lyVAf4m=OTZnloKrQYtAxpyzEAm_e`lAS!WH!ElvS_fgtN zvNFm!tnmGQJp!~|8nZ%woXCjylld0}0Q3iYzamcjRBH|JN?2)MKA7-qp?yVzmHcB8IxtO@*Bn$fic3%7k=k%g_1EPM;}GqEmqHhb z{8`QpIG9%+@(+<_JWjK~858dOymx7w)zQt_fej8vWF-%!xAywb2(u&d5=iDcj4iMX z`)S{d_tsL?P8B+aF%M3A@#UV0M(>Q_rszA`dO&)o?uuD*%zNntp^L-sr2DWfsFRB$ z%B)MLHTZ+@Cpx#x5RuHIaTw`e0~gcL8YdCmQiB|Q8QOUuv6gf{6elcJ?%M6k|D=xd z%_eL4Norlju{?1n@&bZc=tI}Hr56cZ)GRfNQO%O|snpcJ3DR!|&;NCKH`iGjrE`zy kjq^*xLV{&=sw@0^bx4moG-eb)Z2 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 ZwO^{cll(l*?-OA2J+@Ayf}MW<_)ngU(9-|_ literal 20024 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 From 4499792d13fe403550c2f55f21080e06ab834728 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 1 May 2023 09:20:45 -0700 Subject: [PATCH 492/512] rework example --- .../flutter_svg/example/lib/grid.dart | 162 +++++++++++++++ .../flutter_svg/example/lib/main.dart | 185 +++--------------- .../flutter_svg/example/lib/simple.dart | 31 --- 3 files changed, 193 insertions(+), 185 deletions(-) create mode 100644 third_party/packages/flutter_svg/example/lib/grid.dart delete mode 100644 third_party/packages/flutter_svg/example/lib/simple.dart diff --git a/third_party/packages/flutter_svg/example/lib/grid.dart b/third_party/packages/flutter_svg/example/lib/grid.dart new file mode 100644 index 000000000000..26e40be51f6b --- /dev/null +++ b/third_party/packages/flutter_svg/example/lib/grid.dart @@ -0,0 +1,162 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; + +const List _assetNames = [ + // 'assets/notfound.svg', // uncomment to test an asset that doesn't exist. + 'assets/flutter_logo.svg', + 'assets/dart.svg', + 'assets/simple/clip_path_3.svg', + 'assets/simple/clip_path_2.svg', + 'assets/simple/clip_path.svg', + 'assets/simple/fill-rule-inherit.svg', + 'assets/simple/group_fill_opacity.svg', + 'assets/simple/group_opacity.svg', + 'assets/simple/text.svg', + 'assets/simple/text_2.svg', + 'assets/simple/text_5.svg', + 'assets/simple/linear_gradient.svg', + 'assets/simple/linear_gradient_2.svg', + 'assets/simple/male.svg', + 'assets/simple/radial_gradient.svg', + 'assets/simple/rect_rrect.svg', + 'assets/simple/rect_rrect_no_ry.svg', + 'assets/simple/style_attr.svg', + 'assets/w3samples/aa.svg', + 'assets/w3samples/alphachannel.svg', + 'assets/simple/ellipse.svg', + 'assets/simple/dash_path.svg', + 'assets/simple/nested_group.svg', + 'assets/simple/stroke_inherit_circles.svg', + 'assets/simple/use_circles.svg', + 'assets/simple/use_opacity_grid.svg', + 'assets/wikimedia/chess_knight.svg', + 'assets/wikimedia/Ghostscript_Tiger.svg', + 'assets/wikimedia/Firefox_Logo_2017.svg', +]; + +/// Assets treated as "icons" - using a color filter to render differently. +const List iconNames = [ + 'assets/deborah_ufw/new-action-expander.svg', + 'assets/deborah_ufw/new-camera.svg', + 'assets/deborah_ufw/new-gif-button.svg', + 'assets/deborah_ufw/new-gif.svg', + 'assets/deborah_ufw/new-image.svg', + 'assets/deborah_ufw/new-mention.svg', + 'assets/deborah_ufw/new-pause-button.svg', + 'assets/deborah_ufw/new-play-button.svg', + 'assets/deborah_ufw/new-send-circle.svg', + 'assets/deborah_ufw/numeric_25.svg', +]; + +/// Assets to test network access. +const List uriNames = [ + 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', + 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', + 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', +]; + +void main() { + runApp(_MyApp()); +} + +class _MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + theme: ThemeData( + primarySwatch: Colors.blue, + ), + home: const _MyHomePage(title: 'Flutter SVG Demo'), + ); + } +} + +class _MyHomePage extends StatefulWidget { + const _MyHomePage({Key? key, required this.title}) : super(key: key); + final String title; + + @override + _MyHomePageState createState() => _MyHomePageState(); +} + +class _MyHomePageState extends State<_MyHomePage> { + final List _painters = []; + late double _dimension; + + @override + void initState() { + super.initState(); + _dimension = 203.0; + for (String assetName in _assetNames) { + _painters.add( + SvgPicture.asset(assetName), + ); + } + + for (int i = 0; i < iconNames.length; i++) { + _painters.add( + Directionality( + textDirection: TextDirection.ltr, + child: SvgPicture.asset( + iconNames[i], + colorFilter: ColorFilter.mode( + Colors.blueGrey[(i + 1) * 100] ?? Colors.blueGrey, + BlendMode.srcIn, + ), + matchTextDirection: true, + ), + ), + ); + } + + for (String uriName in uriNames) { + _painters.add( + SvgPicture.network( + uriName, + placeholderBuilder: (BuildContext context) => Container( + padding: const EdgeInsets.all(30.0), + child: const CircularProgressIndicator(), + ), + ), + ); + } + // Shows an example of an SVG image that will fetch a raster image from a URL. + _painters.add(SvgPicture.string(''' + +''')); + } + + @override + Widget build(BuildContext context) { + if (_dimension > MediaQuery.of(context).size.width - 10.0) { + _dimension = MediaQuery.of(context).size.width - 10.0; + } + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + ), + body: Column(children: [ + Slider( + min: 5.0, + max: MediaQuery.of(context).size.width - 10.0, + value: _dimension, + onChanged: (double val) { + setState(() => _dimension = val); + }, + ), + Expanded( + child: GridView.extent( + // shrinkWrap: true, + maxCrossAxisExtent: _dimension, + padding: const EdgeInsets.all(4.0), + mainAxisSpacing: 4.0, + crossAxisSpacing: 4.0, + children: _painters.toList(), + ), + ), + ]), + ); + } +} diff --git a/third_party/packages/flutter_svg/example/lib/main.dart b/third_party/packages/flutter_svg/example/lib/main.dart index 26e40be51f6b..42ee8b0ce1e8 100644 --- a/third_party/packages/flutter_svg/example/lib/main.dart +++ b/third_party/packages/flutter_svg/example/lib/main.dart @@ -1,162 +1,39 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; -const List _assetNames = [ - // 'assets/notfound.svg', // uncomment to test an asset that doesn't exist. - 'assets/flutter_logo.svg', - 'assets/dart.svg', - 'assets/simple/clip_path_3.svg', - 'assets/simple/clip_path_2.svg', - 'assets/simple/clip_path.svg', - 'assets/simple/fill-rule-inherit.svg', - 'assets/simple/group_fill_opacity.svg', - 'assets/simple/group_opacity.svg', - 'assets/simple/text.svg', - 'assets/simple/text_2.svg', - 'assets/simple/text_5.svg', - 'assets/simple/linear_gradient.svg', - 'assets/simple/linear_gradient_2.svg', - 'assets/simple/male.svg', - 'assets/simple/radial_gradient.svg', - 'assets/simple/rect_rrect.svg', - 'assets/simple/rect_rrect_no_ry.svg', - 'assets/simple/style_attr.svg', - 'assets/w3samples/aa.svg', - 'assets/w3samples/alphachannel.svg', - 'assets/simple/ellipse.svg', - 'assets/simple/dash_path.svg', - 'assets/simple/nested_group.svg', - 'assets/simple/stroke_inherit_circles.svg', - 'assets/simple/use_circles.svg', - 'assets/simple/use_opacity_grid.svg', - 'assets/wikimedia/chess_knight.svg', - 'assets/wikimedia/Ghostscript_Tiger.svg', - 'assets/wikimedia/Firefox_Logo_2017.svg', -]; - -/// Assets treated as "icons" - using a color filter to render differently. -const List iconNames = [ - 'assets/deborah_ufw/new-action-expander.svg', - 'assets/deborah_ufw/new-camera.svg', - 'assets/deborah_ufw/new-gif-button.svg', - 'assets/deborah_ufw/new-gif.svg', - 'assets/deborah_ufw/new-image.svg', - 'assets/deborah_ufw/new-mention.svg', - 'assets/deborah_ufw/new-pause-button.svg', - 'assets/deborah_ufw/new-play-button.svg', - 'assets/deborah_ufw/new-send-circle.svg', - 'assets/deborah_ufw/numeric_25.svg', -]; - -/// Assets to test network access. -const List uriNames = [ - 'http://upload.wikimedia.org/wikipedia/commons/0/02/SVG_logo.svg', - 'https://dev.w3.org/SVG/tools/svgweb/samples/svg-files/410.svg', - 'https://upload.wikimedia.org/wikipedia/commons/b/b4/Chess_ndd45.svg', -]; +const String svgString = ''' + + + + + + + + + + + + + + + + + + + + +'''; void main() { - runApp(_MyApp()); -} - -class _MyApp extends StatelessWidget { - @override - Widget build(BuildContext context) { - return MaterialApp( - title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: const _MyHomePage(title: 'Flutter SVG Demo'), - ); - } -} - -class _MyHomePage extends StatefulWidget { - const _MyHomePage({Key? key, required this.title}) : super(key: key); - final String title; - - @override - _MyHomePageState createState() => _MyHomePageState(); -} - -class _MyHomePageState extends State<_MyHomePage> { - final List _painters = []; - late double _dimension; - - @override - void initState() { - super.initState(); - _dimension = 203.0; - for (String assetName in _assetNames) { - _painters.add( - SvgPicture.asset(assetName), - ); - } - - for (int i = 0; i < iconNames.length; i++) { - _painters.add( - Directionality( - textDirection: TextDirection.ltr, - child: SvgPicture.asset( - iconNames[i], - colorFilter: ColorFilter.mode( - Colors.blueGrey[(i + 1) * 100] ?? Colors.blueGrey, - BlendMode.srcIn, - ), - matchTextDirection: true, - ), - ), - ); - } - - for (String uriName in uriNames) { - _painters.add( - SvgPicture.network( - uriName, - placeholderBuilder: (BuildContext context) => Container( - padding: const EdgeInsets.all(30.0), - child: const CircularProgressIndicator(), - ), + runApp(MaterialApp( + home: Scaffold( + body: Center( + child: SvgPicture.string( + svgString, + width: 500, + height: 500, ), - ); - } - // Shows an example of an SVG image that will fetch a raster image from a URL. - _painters.add(SvgPicture.string(''' - -''')); - } - - @override - Widget build(BuildContext context) { - if (_dimension > MediaQuery.of(context).size.width - 10.0) { - _dimension = MediaQuery.of(context).size.width - 10.0; - } - return Scaffold( - appBar: AppBar( - title: Text(widget.title), ), - body: Column(children: [ - Slider( - min: 5.0, - max: MediaQuery.of(context).size.width - 10.0, - value: _dimension, - onChanged: (double val) { - setState(() => _dimension = val); - }, - ), - Expanded( - child: GridView.extent( - // shrinkWrap: true, - maxCrossAxisExtent: _dimension, - padding: const EdgeInsets.all(4.0), - mainAxisSpacing: 4.0, - crossAxisSpacing: 4.0, - children: _painters.toList(), - ), - ), - ]), - ); - } + ), + )); } diff --git a/third_party/packages/flutter_svg/example/lib/simple.dart b/third_party/packages/flutter_svg/example/lib/simple.dart deleted file mode 100644 index c93b44e3b592..000000000000 --- a/third_party/packages/flutter_svg/example/lib/simple.dart +++ /dev/null @@ -1,31 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter_svg/flutter_svg.dart'; - -const String svgString = ''' - - - - - - - - - - - -'''; - -void main() { - runApp(MaterialApp( - home: Scaffold( - body: Center( - child: SvgPicture.string( - svgString, - width: 500, - height: 500, - ), - ), - ), - )); -} From 71a764d3a9e3adfbc05a9c376b13898240e5508d Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 11 May 2023 16:06:03 -0700 Subject: [PATCH 493/512] Update widget_svg_test.dart --- .../flutter_svg/test/widget_svg_test.dart | 23 ------------------- 1 file changed, 23 deletions(-) diff --git a/third_party/packages/flutter_svg/test/widget_svg_test.dart b/third_party/packages/flutter_svg/test/widget_svg_test.dart index 350234130518..99c270aa82e3 100644 --- a/third_party/packages/flutter_svg/test/widget_svg_test.dart +++ b/third_party/packages/flutter_svg/test/widget_svg_test.dart @@ -457,29 +457,6 @@ void main() { await _checkWidgetAndGolden(key, 'flutter_logo.string.color_filter.png'); }); - testWidgets('SvgPicture colorFilter - flutter logo - BlendMode.color', - (WidgetTester tester) async { - final GlobalKey key = GlobalKey(); - await tester.pumpWidget( - RepaintBoundary( - key: key, - child: SvgPicture.string( - svgStr, - width: 100.0, - height: 100.0, - colorFilter: const ColorFilter.mode( - Color(0xFF990000), - BlendMode.color, - ), - ), - ), - ); - - await tester.pumpAndSettle(); - await _checkWidgetAndGolden( - key, 'flutter_logo.string.color_filter.blendmode_color.png'); - }); - testWidgets('SvgPicture colorFilter with text', (WidgetTester tester) async { const String svgData = ''' From 1373fc3508988fd15d2571380ddcffd4c40c3ed6 Mon Sep 17 00:00:00 2001 From: Mr John <38257989+MrJohnDev@users.noreply.github.com> Date: Thu, 18 May 2023 08:33:28 +0700 Subject: [PATCH 494/512] [deps] update vector_graphics to 1.1.5+1 (#923) --- third_party/packages/flutter_svg/pubspec.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml index fbf18e770a5d..0f61a414a773 100644 --- a/third_party/packages/flutter_svg/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -2,14 +2,14 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.5 +version: 2.0.6 dependencies: flutter: sdk: flutter - vector_graphics: ^1.1.4 - vector_graphics_codec: ^1.1.4 - vector_graphics_compiler: ^1.1.4 + vector_graphics: ^1.1.5+1 + vector_graphics_codec: ^1.1.5+1 + vector_graphics_compiler: ^1.1.5+1 dev_dependencies: flutter_test: From fe604e59981a73003a2e9d070f80a391b75589c4 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 18 May 2023 11:19:24 -0700 Subject: [PATCH 495/512] Fix analysis for CI, update changelog, roll v_g further (#924) * Fix analysis for CI, update changelog, roll v_g further * Update goldens --- third_party/packages/flutter_svg/CHANGELOG.md | 5 ++++ third_party/packages/flutter_svg/pubspec.yaml | 6 ++--- .../test/golden_widget/circle.em_ex.png | Bin 14207 -> 10224 bytes .../test/golden_widget/circle.em_ex2.png | Bin 14207 -> 10224 bytes .../test/golden_widget/columns_and_rows.png | Bin 32678 -> 25790 bytes .../test/golden_widget/ellipse.em_ex.png | Bin 8367 -> 6534 bytes .../test/golden_widget/ellipse.em_ex2.png | Bin 8367 -> 6534 bytes .../test/golden_widget/flutter_logo.asset.png | Bin 10864 -> 10275 bytes .../golden_widget/flutter_logo.memory.png | Bin 10864 -> 10275 bytes .../golden_widget/flutter_logo.natural.png | Bin 26474 -> 25928 bytes .../golden_widget/flutter_logo.network.png | Bin 10864 -> 10275 bytes .../flutter_logo.string.color_filter.png | Bin 8160 -> 7599 bytes .../golden_widget/flutter_logo.string.ltr.png | Bin 3722 -> 3389 bytes .../golden_widget/flutter_logo.string.png | Bin 10864 -> 10275 bytes .../golden_widget/flutter_logo.string.rtl.png | Bin 3721 -> 3389 bytes .../test/golden_widget/rect.em_ex.png | Bin 4626 -> 4070 bytes .../test/golden_widget/rect.em_ex2.png | Bin 4626 -> 4070 bytes .../stick_figure.withclipping.png | Bin 20756 -> 20024 bytes .../test/no_width_height_test.dart | 12 ++++----- .../flutter_svg/test/widget_svg_test.dart | 25 +++++++++--------- 20 files changed, 27 insertions(+), 21 deletions(-) diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md index d0f7a7225e21..91f21a0db508 100644 --- a/third_party/packages/flutter_svg/CHANGELOG.md +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 2.0.6 + +- Fix test-only issues with latest Flutter stable (3.10). +- Roll vector_graphics to higher minimum version. + ## 2.0.5 - Allow malformed UTF-8 in loaders. diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml index 0f61a414a773..814e81676401 100644 --- a/third_party/packages/flutter_svg/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -7,9 +7,9 @@ version: 2.0.6 dependencies: flutter: sdk: flutter - vector_graphics: ^1.1.5+1 - vector_graphics_codec: ^1.1.5+1 - vector_graphics_compiler: ^1.1.5+1 + vector_graphics: ^1.1.6 + vector_graphics_codec: ^1.1.6 + vector_graphics_compiler: ^1.1.6 dev_dependencies: flutter_test: diff --git a/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex.png index ac9af33da57ca012b93e930391076a29ae6dfd2f..9c72bdcbea280fda4aa3b156426e9245db3ad49d 100644 GIT binary patch literal 10224 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 MgYEh|7Tk#c1$ZGXHvj+t literal 14207 zcmaibc{r5q`}Z}&APPMc6`3Am%T8!ynKq0pMTKlrSqf3Zs3|e6>PgbrcV$bKMAnpP zlOanHY4cQL2-WwQp`MX=&s)Fu_j}*tc#q@lk81Aw+RpvF&hv9$-0ot(M0%w(LTCxq zVT&6=Vnl@So>CI1MwPRduU;h9BaQo2Wab;7^QHzy*Yeh`MFt&SN=~ z@0ckg9=--&kLG{vP+_Cf_>KVi%TA}2dOLY&@8MI@sYN%F(NZy~4!z?m@B(-F6+6Wh z7O$c1I(LV7c65- z9pZ9Nx7;=V*Ff;MU;4PQ!s8*b9XRrz?qn|Cv_YT1wI_d7Ov60T9oNXOZRpG1TkXG@>6dwa zw*zm6E>DgzHd89*)lv;Q+zdMAL~fbg-2)#`LB68=*oEVEvh6!#%{An<3I0Qp<5sP@ zuIxXkAqrp%-RZGaJ+^73f!-6_QT0-3se~KNX7Pc+bHQohdMa{%aodW#odkx|ZdZD2 z{RrOTFs|1O23=@2vrSTE?hIL-$Jc?s`*hYbkHG-zTZeXM2e-ci;)BQ5J z4SOWBp5HD+v6HZ3rZ`d)~8l(K1vkWqMuwGW2 z(f|vdp1C%e|83-m4q20Hs6oEL&^$2qnxy8yy-PnfS7K!_*Z>26XcG_1EU1T-Cf8Vp zxsScsJNWd{s9o$I#p#j4Upb>_11c|OQP|C9*)`U-tu6P))00)6TPj4gkLWNX*hd2+ z=c=57gC{5`!GLh~;_e21{m|9Y68>juVo0uJ8)qxkrDtciUZ2Qs!U!d-h9T|^LGIB! zrSxr26+TJmDxdvQ#`Hffl5t;(qDxsu#^W(xvv`B<^nD>;-&)E!C9rQ5^AkvMA4Gp5 zZDK-QvzcVjiCD6RYfn|Y_>8ICmwu93SC#&rZ-#wMRSY6J-?J~__Ri7Bd6JeE*?_zE z@+Z^~9mqaMDoq`VX=W&+^Y*yC75%ls>M6m)$>Txxw-~Ew`DyGJqS-A&Z-HFpBV=?; zS}M08=G<3c$X<3nkm1=NlRUelM3639DVAVJINN$R9q zt+O@*naXwiBeDZAPG;ganKITixOPQoi7t~Q>$}AgE>E}#)20ORftu-cvSOSr9pYkN zYxVfx))u3?tBJ=PCagHGnk~86CaJc1eNC7kqIXb~voLWQ_qYl^lHwb>#henpkwj;l zMtVA)ce%+RZo5mzE|9a+AB3~_ zZ~#0F)?dR4VWKb zq8Z+6(ygwS%*_jyDrOX}C_hk~mm6Q4-j}R0WGTa8`Q#Mm>`d$-RGvWz3WT#}W!{mV z(Y)z0QQf~nv4qwv-j~b{EE0qPe^fjvH6e^Ou8v*a$+O!h^w8$-ms70nKI5H)*-^Rp zhc+*3g_}Q*R8sT$EoCVCzjeCh`6l*Q?2*KcttFhjwyCP!X=Ndbx`=<+)h`z~?{n3oguj(q zvS$>heB=`FL0vE|X!IGjTuf2YCcbTd*^DOm9e%7`<8`u>6Lls1=UUd^i&@tp$vLi) z>1VTNRCs;Q$w)bx#vD86Fk{V8r!Ft*>UY41jP-^ZS}B<^rj?>kzJPAmR=m*~gJ&fw?ulLL-jXQYT(%k?)|-2-t=yHV^sb9=sNkWINI z;1HBoWV_Li=XREZzI)0AQ|x*L$z8*FytCN5y&B)zKQN=2K2;H_1X`V9(o**ZezhL| zR`P5QydOJzC3vkXxT+dh_~mwr-G$I-oTt{{6h8OE;`R$SgiKnApiEm0RlM7wBiiEI zz5`5d^3tMqsT+|@2gf;A_8DMDL0^@N;T4^yBWj=&uU07}wT=74`iW41t1Q>e#!X3Z z37d5p|6+S?kAl140jxLGv!+Z$$?Y@*?pJHo)6CpPg^x+!Txu{DwY^B}cS_f1MobXV zT~pk_g6?4R4oP&Tj;!H5(Gu*4E8L1(QDd1OtU=y@J#Qd$H%!Fj^#Mnhfbv`)5&SbS zKt>r3J^HoGZ4>fHleig9@dEa}BP?au7>26iIpP6Q<34jl4Z}mZVu;;R@{B)HxfvyI z!>y>c%x}w&!qj29W5)I^2mY`32b<9iyw{?SaR(6$cmjJaPYmC~75Upj> zp=&ve7AFMc!e}zp9HI>pt5)YKbcWf0LK^ugCNXZvkS)#BE&!p&-lXw7Qsp7#O)|SF zB%5$sNlnh+1B}FnT?GXu*_S}vZD(p_Lbof?f0EP^U<$9%nJs4!CxH*kz}GlJw&&C} z??Mm2CI#4+@Z$z6$<++`f}e^>yKX>CdXkgNy9TC8QJ3r5*IiZWxdE;EWO()EdXrWN zHQrAVt1XrxGF?i0r?P1{zB#G1n6FwHi8$@r%;TBd6~K^pMXZVf1D=w*@B!o(wTL6- zYBX)b&h^m1h1-*o=`&y{ z)vGFdZTMmM;1{sQYLh`BKD2~2*~Ykws)OWw=O)EHmk|Pv{^;2DvDp`Smit#mGW{mx zDHiL+Y9Ks*pxP`iUW^9z8*>d)hH{31ov#&>NYl?|9n44bliywg%^s_c2)2)H&dIn{ zFN;s8x;P&m2ca`C^8Kn2F=Re2JCyTdz}?zb=GEPchD7qZ2xoyi(8$U7w@f9+_K+%G z*;m1rGVYU?nWf+j8h6``PS5Q$1wPsJJ$x%3fhGg1Iq#j@{PFhuWjf5m6UxZw z!)ms=@UMY2topWCnca{zcDv0PC%e@n+8zC3esE`63^=KR%eM`P3>$k=lM(kFxE>T9 zMUCd)A35s-)^8N^$!6Ix?-V(tZ1$s_KkEg;S+#!yu1rWa=aNBh&lj`U;E*rl z%195L_U!T#@uIwB$pD@CoB(%FJx=o%C&AypW2r=`P$3Dsex&q4{GkjUa-@g68#h&L z^BR?Ls2^>juI{yzfRHBVGZ!Y=wzIT>_R=(RG^~3xS>*);h+YeiQvTE5F{d}~T^=i} zJ0Ida>qw-7~~u_T~2627mW!kgM-G{p_tlw(uOOAvBkO zAcqgKkFChb_y#IEDCrbH! z)bA14l;#O{p?lyqn?XydYU6jAkoc3q!#mylnrgu^NazD8ztoa~H>1_~;A##|}DKiHS$8~f)QVFD~Oz3THK2jBKD z?vYgNDu_dNZAVQ~3p=9jgBDds7h2=IIzl1&Ko&p5hVq6XTzKYR&1LEN-~Bm6%7!!% z*>!jKza6Y=>9sBd{bFtd2GM%Vo6?k;50YdYfVb4x`{2=OMb;$-JSs3c)RgXBJsw{Z zXVCM68rz8J9PgxtJ@0A9C;CaS((#1%;=I4CY=PQp%cH)28<4888>SJq8BbztxO>61 zq1+=|>qozi9BjJIkf#mXh2m>6(!pxc0RKOe>FM>dxQgy}CrVnW+I%LD1<{?=-DI$> zDVS_Cd_Yy)b7;(o676h@ozz;^$*}dErFeCOx-ri97eX@}MR7~oI!$7U8sfBNo~B5y z%V+hA-l}uA?w}ynWmCebrGv3}H^E;JLn(188Eg;OZqm1JQM+L3(|^^md(nDg<4yHG+zDYJMqU;Vn|uVU0!*I zvnFwR@~z=LA7z60??)RCX%e#qv#=e9mU)^ZwQ>ftoehCH{?r=gEB{p}WBmrV$R9Nt zKsSEUWOh-zTdXNC&qyWPU62DZ&R)#GyEX7Rdi+poqB4JwfHYtKpfh3{b8+<24oyG>PdgUUOsDG)TqtRRY)s3a)3-Z9 zE+p=B^VBko92ffA0zWlG6DvtqQ$UM{{?;T8w=1w`+d0_NUtjOfW*}O-ga;)g&$4<@ z0=>GC658tdB1 z&77joCvatE8fHD?KPK>K%Gc19p{#nod|n}`$?8wpd@Byr|e`or3TYn`)V^wjx-`>ti3f&`lirPE8sJ%o*4H!O_cBZfMA8ebk z2;Aotd+|uMU+5&SoOXX%l4br+xV8Q|ZjD&i%9{LhdwzL8Wl?)u7hNd5h)3^&v?LdA z^q0Lh=x&<2S#XaOKlN!Ep_Pqm-J4Ekc7Gq(NXwZH#?ue1Uf8F8bFI4Vprv@i-8sdi zto=U)mIxj4>f^8u9h2GpE^Bj5M#N)raWrQ0rkchvx50TmQ@|X>rw_f8?Vt9r^B{HhWj6HTa)2 zc^Gw#ug8|_sXHQ?iq|I&tKtO2LEWS6B|a+^;w%9{;luEyg7lj%=+(#A@6RF*>Gtx%b5oaw3Kj$Fl2|$$LDc1-$&0!1$d5<0(N+G!(P{lWgGYF5{mm;DLSf^Akqug3dkaVg9 zp)rZjKVKD`T)uELykfc#)hghq;Ry{aBd6%{G|NJr4!bK=N z;E?#Lnvao`@ysS)^U*h6Z^UG9sBOs2@vCPL-D`r_yH!`|QrYa3O`II!1bo(DZl93v z-KCo@b3z5OnXZ+K1`hf6Eorbq=xvtS9~FImJ*<9HI^}!k2vt^j-)h7%Xf#k7O@hid zSV+~-Pw{}YKd>aDT1%4O{ub^kW7kvbX+v+MP_@NNb3M;1_mq-8I)i)hcw!N{*V>5! z@#5*8MFV@U5Q@UP-ruIJYIxo!|>zs_uZ5P1swX`m9=PKY&W4OkL~C9weQcxh*Fv|8(e7`0S_L=i)1XK_y>*u!tR~|Kicf0%t4(;xGy=Wl7Ref{BpNRD`QeJg{g2SO# z5CsNku7tv^ncT6>~3PYJQIy*s+!mi%@T293<;>(~Fd_p((C zD&+U3tRAA>6KR2uq?RJumx^n&R7H6RVYTN^?`me^bVLvA$Otueu9V*WC5^xfzf1?} z)6EnsUU$hjO!INb(==4uvu>4)0~GeO$Q65+BUY7V7*n4x`N&xz>DRiWh{dQ)JH2b@ zq)eJtff%Ytk0e&Fm6k#jTRo^que4YuU#SX?wW64|D|{_6JOZItQlUDY=iW8Yn0*Mw zFOsToG^CCXggMgF+q~c~<@_orvA?yHNNDy2ix7PvWxuw=p|LxUgwDgg=S~joqC_jN zz@xAXvt^U+5u&(zFw49nOZxjk51{B&8%9yj@1JE&zMoVOdKc_W_!;#`oF};oGNmz_ z(6z5hS7{R8>mjr%5PP*5M{YTSiMh7q^vUMEGHDhvh-2sF{=jBBEzaCP9KBjk5dVJ7 zqo*B5l?_!DN3_K%^)2=I@7L4Mm@yE`hRk^_y?dZjHsTM&x_`U=^s?z1o--aY(ShC7 z*Zq#m0&Aw6U2&&Ur)r8=2u)p%U;6N`<9jR-MQs^DeD@3CV;5MZ2Ajx!d!HeNSjPJf z5p>6j10vzdj`lx-<@>iy-+@uTm;VFXX<>pk5usm!FnBv?^GqiU>y}mANYArageb$F-Vgr5bbf{lqj>VLdz_c|18J2_k_eq|15aMiT2V@YI!rT9F@4*jb7|B#2-aF{C2&dbnx zK~g%f0^2VQJIYMk*FQXW{MYl}5**3~jzlc1>yxbe@nSA8y4sri10vgw0bSS5dJ-gl z;1DGY4Eu)OLzt|2FX*v52TFzMTXi{WX9U>G5=^IF@1j`URzS2*R$}7cKcB~c?82k! z9eJl^K`oc-VZ$!hlw)rewIBVzbaeP2=5Bsgl+p5|mn9X?di=LO-zjH>eGdW$VT7r( zFM%f+d62Dos1Pjp^^aPec}Qs!n*G=*kgu_CnZZ4@*H>fStE9G;u~?aL@7=dC3^>WRJ-!`)pF&De5Hu|(#69XsOcRz!d^}!xkkQ16d=)zh1?j|e6y(T5Ar(Q}7 z_3D`A>y#cli>r8&*UchX$Cn|r`@wfz&q8Y@`37({73a+qDxSZWzF;ngstuzrbF#iP zvBGwPoqgv*FbIR#;xw8~y>G??7QNdcs2ed;sFpbK=5#74Uu6$4qN+@kKCral(sw^f z$Xx6N%zr(BpcMFxP;|^4(&p5;4p7LU0mp$L43{Z&YrlH z`!K)!Z;DpIqnU~*DeH^R|3sYCp6U-QD}5+`WmiKaezFpar3y)L)C46Qimpw0G7Fvs zV(s!IljKe}LFV3bklHXc@^!TMcPsZ(JidhD*?KFC@#t;4(3ZCOyDw$(2>8L=x}{;9 z`!Wu$osy_=2Y9s0+T|i=hRyJZ&8j+tlvFV+fD`>G4(^4@41b;4CU4j#@Mj)t^7>~n z`-1u1n0u%o{R|#$C&jprxhDRg%adAX>`Fy-a8EFiuDh zi}d_o9P46`zW7PVbKF`!Lvn@vxIKfXAG1m0%{oCC6d;>X}_iNzjtWZxrF6 z@~Ni#+dR+I<=~E}8X}|2koRyoNw`$EEGZ9sloN6A+os`)G8Xh6Y`7j0DX_I-Q>@a= z0Z7Rno9n?P-Sa0!t@0jgYVwpg(u7><+N}XUiqBIS}8eEB&Cg-@;Y#ZO@x!9LPEz8lr3)Z~)57)YfAC zH7RBLRYRv!l_BnY;;xjG2-r^u@U~HYQ;k^v&>1Cy!G)Z9JMQ)p8Kk^f?anW0iQq!- z>OZg)J4Z2em2%N#r6k`s)m5*LDIylXs(Y7+1_^Puxeq0+VeiQsa$X3%UdwbPlP^{7 z=d7Q2x?HairuulogF+~BcikK{`gr3VQI2Fll#t*3Ke3_t;1Tx;-V7X zo!C|b2$!iX&LY-_@%iNyq@kQX1vyA8?OrG9@xK5gi&i*b0(4=^E%}J8!aF0I|L8wU zf?&5NrwkD7EK@*UXWWRV@3P6@*-Cz&L1^N~OO^C1;JuO$&d1O7r*89!o}E-IPz+?l{C6!W&)hkL*~e}b)8OU` zzLL^qzf9oJTi(R)YyYw&!Hr1=ZvK)9?CA~u^vI5(=av#i&lWkb!@3Vr?_2bPT%DRb zYyDlIZ2Kzk2Ide?P~Y1;!=AVFL2DDLO0NPNF%B@d?Gu+qi=QM;3A7-;uvl>%r{hgO z$o{eTCtRf!ZUo%N`ssRTBCin{ zXr6utM*C#LX(peAE{s0^Su){95aBV9rmWm2r|k7blXy`_3K>bgak8aFnduWp{*BQw zD{XiN`Ax37Gd!!y1?F{?{~;%dM>G4pO9T*bSocExC|HA>-G^1++8&k#T0(k(e|48n zAW?zCPhf*ru)!GXsy4BN2+3YXEJZS53yz8%BkXZ%iCXUxb$5!>M$m#|wVx%U9<@W2 z+`?&N)d5ww=cnkJrdmKkQ_<}Jelh0$RrX+AHx5NPa6_S89;PbhnR|6Dk;;A~EFt+H z#AckGhbskC%jkq6C^c#^4?@R;qSX?>{DPvk98{%6jK|opdC#%(ulht`pm}RA6u!*W zEpSacx`fG-uq0BZZung^s#`ULcdO?`mWeK5)y<_lg-U^%`4O<|-K+Yr>o0+TGz>qH zvQBz&I+l1<^f)LbK~HU;+cuZxRBx8^nj0E>@{(cHbb>Je{R~d8T$Bmnj(X}d9!yZhb z8oL#fYBchUPT; zvV@w=&eq)}kqoGg$3@))8Ix_|^4X@)P(bGkc+X6-h0su#DUHMgnxUjA3Ww@EhjQ|$ z$W%>PJy(x7@;JtVdkNcDVti|7zKEl&Qz;e(&B3P_gag=i|L25Bwtt8!eyr8Sg%W

}+Q@iwM(mxSY_d`w|H&t(A`cpys^;##dht)>SiNw$%XBp%1~%d4oNa)Ce|++byOL z6eiPN6RZJE6Djm}(46T8!7A_uhY}b#NGaaFY(YkDX)ijD{O)!1ws|TgJ;omH^J$V% z2%nU3_`^ep=V%`uF-S7LcmAkr+AaRCE2Q7;nD*4W6gD-J#cL~P=J&y-PDSkDoi?n1 z)6x#?l%W<=vr3C?=cC5B=6UTt$92J zXunbHWA=$^6==JhDBq#g_`OWjKstI5^v3Sh6CF_|NZ+;{mAlKn!u#NjEIi?jO zeFrp2kBx|V>JkDBJDld!HC(%^yrD*!tyjY1g3?0gJL(F)=Cnz2t2392F~vcL-1LkW z0oK<{#SO)qB%88Zs-TOYy!4j$T$s405+T6Mp!=I9(-kbT_tl9sTLs)em%e8?!1$of zT}WO18d^c?{&Uf3WOM;rBtB+N2v`DLPtIBTJA+<}dRpbF2_`OsQuT%~jl8v^v;5*4MJQw<&TSVwQ1@}4GB-<8XNq0a(0JDl25mS~R6kX|X^2_G!!q}6Q zGV3zLwtztB1TT6z!d$3=X7D$(RKL2}CF@w%4ojV+jK=^-X)88d+Rr0M_yR%}_d09w zcHj1cWlTFb#bI5I2m@1Q?1VChcbgE(>Trs+UhtwU?_=2l+#ML~nb{SY+)@IZcVPFo z)IZ}7ffgipF0WVvokR_;F1Rh)>D1Xou~AB>bi4dZQHvh;8z>fM%kk*Ut~b!w+DyV^eth24&rwr$yL8LGeTATZ;9oc%X;ZaeaT_a zzGB_Jqs~q440{h9WI%H!od+-lH1J77m{zrQOj8qg*kD+pb&x?`0uV)tJev8G)o*n> zjBAhKFBAv?;;>k&Bi#Xdj8U)6%0%ZNRD`LD(;}=c92QT>oIP}$xs$yOLv9p0-cRE# z?T|DYccR$+MwWgc*@Fxzr7;E@1Y`7l_n|M&xvx!BFA4A3>-FqsvK7`awfrz2wANMo zzknmvgwV$+pM5gb1sN$Vh49+$y;o*OkFFXeJ%g11m?n>6-ZGGh5!=r_NGO1^$$%qn z#SsAcxN;9d^Qaroad?%<`y6N^W2}wKw zyp-FhfR~b!%Hu$T&NI2(O*mDf0XH0RTCZY~vHJoPO^bUKR;^yEq{WQM?0N!ZFFvF1 zxxXZg8(gC==Mzh}M1>W+cSC8CYt=X;W88}Uj5R$jUD@o(L9l;|T5B^yu&!WiUN#2b zA~O%C3DSRe9oeM$T)#ZG#LiN1S_=TKhFRRv*8XQ81fzeVfBDAPj)-LhXc85Q3<9== zyiemL!9g{jz0_gu&ito~hzJ1>`;U&~4P{0qTU9fbvlboMYd(@e54-;s^h6sp;bF>t z;fPOeyr!s-RL5A>!YjI1j%8Q(<9@%cL<3uK2|s{-6r#r))ax*tG~e2hj7z60!(sHzkVbH$TbrZh8V5#_C zt-)emU7+SIOpR1@h+&=!5OF@K72*L$;@7T_*m4XV4p>WF0E3pvFt@O6UAh2%jq^-q z$GHl;0c?ul!`_n5x(q`_z{>xbYccOL_5MpsInLS`U5%c0C80Z@84qW$jO2gA`ZhpL z%Kqg&ifcSK;VyXEWN=GIYvd*dCI!$W@mBdrl6WGjEQU1p_RwNRmI#_na?8B|N329R8#KNtJioYwq|tLxas~cZq%Yfc8+QUi zGGJ_3+3u7BRR9QfG`!^^=qF{vxh+Fau={FKh7F&Nt^%BFb+EM5Z_F@P*WE;+=LT+f zgbtTHbahx?i(ifnFd>}1>JCso9VUbAf6=y(^Zq3%E;Y*|MPK9tc;Sjf03DYDzN3hL zxeR(rdYpFA_Tx;ig_KkZg%+}m1mn;OKF&PIehQvz-H)p&06XK&LqU}@^FK)GbYA0s zBc*-In3a{g(YsPsFL|N$%Zz3FyVA1Tu{f@$D7lrsM}U^~lKZe5G_ zgcW6Y)`M+P%1@}#fIEu>YtD@_)`CGyGD=Cz9T-Mbtl~{;34h6u;b_`txClwG9&D#5 z>oN>%v)M{oqT*v|Qc(}w*m40n5!z2jPs1+CR)n*+@62w0q*TmnT(5;M9Q#S-12j1e zYx=`$K)&Awa6BX<7pX3e0^vWwtM}Zb&Ka0}Yma3{WOg&)3k9Q?<@=oyEc5Sbit19V z^v#Zj=SphYaR=QZgV=o?VfSBH%A!L$M5mkuF#Z*1E|r>>1U&&Kqx1Dz%s9vQSGz>s z@g2CvQ}~Bl%7aH_hf;HAJln65%sWDrJ&?QT zJk8s2PIDXCVvr{`!t;4!DUaTjusD|emE-`C=+CE`*vAkn?N7(P&f~SD09K4`7n409|UR z#Qyp8XTtNH$uX81YA#*zk)^ZynLD9rK;ZmaYjhfSQ>JNun&96Qm0X?@8~e^d;Y&^b z>>)>+oU&Qx%8fNF50JGNt4ec6F9V*nnKZSVOcg+|6g4X{p@ zfI_daDE13|(Vm{7_nr=`**s3$ZRLsyc8m#ERMteiB#IZ@2@6$~M&_IT=PRGS&K=Z5 z$1c|r-VM@^zo^tfJx$TR5Cca;C5+6P7+y}H22)2W=4-!QeivkQcAcCTPw}cDmfIPX8iXn{eTR zQ!;)_K=-j^6WvMok5cO&@5`a6YHO^Hcz#ceY$tQ&+6SM$PXj9#yUS_)`KO7DwER`V zMxzG)(MtdGr~x#552d-k&`~%F%JK?ATZdcc(v1(EhIC-g$sYDSM1oQbYQJ`uJYu_Lw;4Mm=>Mgf{QB`Of_a}a zdD#_;(pZ9Tw`rT0@w&;BpJz?~x^Q7OR9b#%=Gq9iHHCJWYYW%^bIfAk$Xbfsk<%XM zllLAu6tG_RpS;V~lI8y_vnFoOkzZznci|}iEl&J(Hqqek|GV>IUbd7DZKT kjN3izuw_fY)sy%N_il;fkEZ^G_8g*ab=gw2iFW#b0g%*9@Bjb+ diff --git a/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/circle.em_ex2.png index ac9af33da57ca012b93e930391076a29ae6dfd2f..9c72bdcbea280fda4aa3b156426e9245db3ad49d 100644 GIT binary patch literal 10224 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 MgYEh|7Tk#c1$ZGXHvj+t literal 14207 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 diff --git a/third_party/packages/flutter_svg/test/golden_widget/columns_and_rows.png b/third_party/packages/flutter_svg/test/golden_widget/columns_and_rows.png index acd19c0a4a3f21f38fdb52601ec44f9b4831a607..105dbecb54686478846c83fdfa7c9d51bbd730ef 100644 GIT binary patch literal 25790 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 literal 32678 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 diff --git a/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex.png index e3a3a585e8fb38fb84930d38fdee2a938602e45e..3244264aae23833ef7e318faa5d6951c95bbae3a 100644 GIT binary patch literal 6534 zcmeHLc|6qJzyA{13Z<-tkR{8Y%|1ifvb4&G(TE~SMaIsApW)cWN*TEl?`zb>`B&T`TIQU?3*E2rD4t{>@4q*r)q-=at_l#H4RIeF< zzq4@jK+#bpR|8L$kGpk;wqb>IjrinkbtRQOS)?V|MQ_bYs5X6)%oDt2$FfZ_%;`;` zMbSf^ptmv)Q=Yq!#tFb6c zU3(cZwuo+xV{UOecS@p1d)Ij0a0YL~Ac)i1z^Eyyeut!rZ*os=NiFAeH-*0`|9*u- z96=7GgX0U!(*D!weq+UTCrel3l=|Z%dhQ|22!@Xyyefwi&Dg+`)AVuNA4YE!C8ju& zRrQ(K5yWC~qwf5N;genQ1e=bNbghYX(u|9M>R!g0shU@kOqfkDq;hiY!=!`cN_@bq z+Kj&WTzPM&dKS*80SbQ?t4N+XTt0Zi8c@I3l27*$Dda*B{5n0@FEM)6W$Ck|F@17K zYGZ>*N#CBX zNbf}I-l^N{0MQP(V=J@18Ui>0Z9a1k!vL64}#(9h{( zKb~HS-E$P~*2~N!P+e_XCUeF-wxSTk#ecT>&g{vS@txF_`FI^@<}A;{fsvj%=klm@ ztHvNnEQ0tw2HKF=3cn6S$n?4{ISbsdmIfP>+Qf!*Ln8ULv1?bPn;?MS=}&0&1_3!Z zHnLj17$w&oONmI_jzJJ3(n3rA{pi*0ol~!-)kKybQBu;nZuf*h>PZ^)Xh}cQ%8?1j zgT~M!W@4Lry$;SLl(6Fver(kGogNc(ui<2I zP)+0o2o%@nv5pG|{C6~LQ$UF6#fgU7bYk%?iv_ME4tBt;c+vT<*G}JV=>dlz?)~Hx zs2*Q=a2fLua94I0-DQ&{Ehc*ta;u>`(%u;d80TA2_@Apa8@wKy9(_vKGZRNdkVdN% zNcM_*$EGG_AV!>A_-I*YYqvNwfV+oG|3{@;1_#=?0B#jq7TLU`bTkXUrf%~m(1W#} z;tak(y(hD5wKgm#1FoOtLp@G}M4NiGB4#UVU!A3%ybooKhzpqIsP#_Vc&5$@m5t;3 zz@t=T<;!^i1d%ddrXkyg1%*4oa`6U3nG&bTO7#SbUtdDXYXe<}=FkT-ehP)BS9(}X z2tlp?*uOSVv(Ho)23GMVndabeU4@665Yw-)m*z!Xfx_0aHzHjovDtHtp5M=8_;Or8c8O>&KC>siPRd|(2tvFrRCtu`? z026{&V}!v55I(7Ms!s7&pWK^RG`qP4kB_aVfZuH}y`HZ5epN#3IK zZN=98p?l$h>TmMrWWb;?bkOqUbgcG1Fh1}oFyVn(fd0xMORA3~FbYQg(5~_e60U8T z@Iw=f_qp~k#+yI@9LonDR{SX2qQy25(huqf8!othDuA20N)u6wdOHtKT0zLRE}`QR zL>9BawiC3g=VL?9xxS~sZC9y-mZt4neJlZhPg}mpXH0Zap~21!(Q(q#U7g<`A_sv` z)o*bHcOaGtHsuZNe~;;YRuq=v`z}j)kg_o-gr7F>^qfLA2|%O$3mrG|Mc7vyGExK* zM9QO$WZ{DSMsP{78;T3i-kG(8KIGELvyH|_v+;7nw(7tv4FmIWyEzIN8uLi>0b3LA`dpK^Fud$uT!v5X^MMT1ciO?vm(~m zzSGAVs3+UP5>f)wo>LU-&5?;{sv;0&M?3o98op0wQ5+_j6Q>+Ef@yq!Swh>zOah0p zDgI^gLNZ#7+)MyqR5G;WpffFomS^0y4sQ zrU&W8d7V%eX1ZhF2Hr|(!W$9|0UpOcVhM+$U^A_*nO?pH!Ei9MH@t@--M-*G#hm(7 zClLFc3{R_?Vz3E?+9e-kiX zMVw7#!}|v-KNm`Z$myEjx5DgT@5YKU>4aw7%b1;K%ns&xlyj~%^&2$R@0>TLmSkqb(B+!iY=YtysH6nT62xVT= zgUfee(^m81GzD>rfW;J}0=p9ABJ{n%ANd5P);JU&5Ezj)`n`Sg#~I&EEK1O;w@i83 z>fZ4HWgF5VUI5IIR6(eqljkI{LLUnAaFKw)XK&R66fwF$fS)QLJ0!t*q#7zvRS?4c z^(GCf9Xcv(i+v&hM#P}s#1L77-^>|2h@btffW+;i403l}yqFN8+yB1(r%3;z@_(I< zv4rr=CU+_!!X8pY-T(B=3_*RX zLfqyZ!Mi@sZpY{vUUe375#KfYF=DRRrW(ZD^3Ry_Si)e7-TR3^LFEiv#O|{XaJbZ@ z=4}f6Iqsk#N=@o73vGS_Le!>;3sF|J{Fd(^W?PvEYg5d?KHJ!dv_9xzHI6(X>GY@H zVMcjTa+jQb?!yYy{u5w!Dtp`?y785qFBhMETwr8~Lwvlk&So=|Pyr+r0Ys0E<_?%a zOS~JK%O`N0XlG?)q?iFg{)Pg=cVl3A*(wQ*1~=U?ez5DRLnVdAJJzCEz7 zu;XuwFKFOz<%6|CSmDur%aqBhkU?2h7i)!)4y_yDfw}xZoA=TLC!<8fEY+}t#Fy$_ zgL&?@hp)Q%+;hTi<)=z0ORB#dJQ~`(BZOA+zD+Fo2|DH7z%e zh#a_D1uhDy-o0zPs(r;x`!g+2=l=kXa3Z=pFRt`g>5bOr&6rNmR)9Qj{#h{J`uNwv zU)sFV)8|&i;E7h|B0Cj}&S@MZekgp*v}3DJkw_XhxIR5W8=a?YF3xfNPWOHT*=+^= z6OuD-pbfi$mlYmmrcGOY&jKqtRqh5S8-INezk0>TxtuRwfj8P#?$f*(UuvlP;E^v! z5j)l7o&~X+;L?OSLJ!_0v+O^mF|a+C(tD+ELF^E$#Kw-CdV{XCG^o5a3-3A4Oi>T$ z&MNop+VZS-mmh<^)-@=|pDmnv7@Bp7UHs+5N9s6e(lPeGTL87(ZmNF(Z1$Z@K__r? z`88qp^%{(}92BHpMd93jqvIMutVpYDkzHGqb$`I(J`$=dZ;$<>D5+In6bK+9ut@pdTR0vnV?*u z9u)7tlu+P+o`*NBx1}wr{4qpCqhYLFRc{97pKRYmvFNfK+~)9kpAO$(nEHh~r-nZz zitp$gu60G#9@)qTI8^LV3)R0YxtQb$Hb_6(*n@gM%2W6i&s17A`TE_GVEIc%f1OlJ zBI_9>6+_CWzXf`4Zy1ZX7Bf8W3G2@vc@gH@Bo$N2VZkvqCjZ^014Z$AXLC=Xb8&11 zi+*F|mKInmGcw%wq9oOY0^f`X+ag4c2_CnYp?Pop5|| z4;EW#5N9IKlz*P~R%ZQNx^I!u8*IuDw=qc{H-yQ)v35MLZApneWv+DOttlk&M@L{A zK@pWQSNw5764Du|{yJupGnP5}6{d&%`95u3J3_*D_%HhHh6uTu>SAXsrhbuYo+!VL z&cd-Zd7ts6|0RW+0yRd^Ffgi0>iox?U}>!xLcwWD7<>%Dzc$x0uRC^x3Ok&}Gv7V9 zwatx6{rdeMRCQe}gQjSVujL?5d-T05x~d7)-l4oM7<}tv&PMwMbD2w9ZbF*iX@di$8ApYEu>o= zhItqp23$)0@;sJ%lSX~;NB$Oup%m&Sw8K)IJ1dQZedp~N>R#>}(cM*@kY<@pU48+> zI8XWBg{CuuhPe#T`JFsWN3Q_~R1S1m8|%;%m0&@z$~-%oF=;&9whX=N&BZc(ag;5t zlOCC14!)XT^E&K3novsa5AS5_sCjLJxPC6})iNf}fEX$C@0=Pjo|4FE;ATe<Dj5Od(P9W^6>R}*+OMT|+)0r%WUzTh>5&)n@A=ZwD%<7I~0VZ9wr z>iM4bo*9%NU=ZYo(Z-SF$1Udp6E+C_!EAZYPH1zi3H#+b(>I3jdXETrN8cF-1xzTs zbNFIk<7hU#IUq{yGmiUHhFcfQ?k9ytK9EB_NP#!B>(AE3yN$V{S6>qpx#l%QXw!_h zh9hnuQ4vjG+&jqhvCEBnkRFuWj%2)w$*Xe6jU4bx+FZ_P5{p&$INU7YX5`?CgB*L( z;{AUZO+wOUy{@(nlHECDyHAkGw7R99DnnS*Dz=t9@)X}+=KNh1UgCR>B?zU%yTf&tOtjHVM~=OOtqjfj!Ve>u zMFm?YLbJr8{cI_*2GnD2*EkwR1YqgKD+3vZuD-HIIXoEk29HlUO7>6$S$g1*U8&aH z?|QaRTGFOb-Zqpde&}lv8R$Afsg~8G1r=wT(Le>ZaVEcqMViO9my1P7fEETyP zj&v4i6Nb|gjMtiEspWivqU4I4h_}{&8-S&@hF{1p=mbJ`jB zQbsb2U%yYyC236%<{uOGoQ8pQq9Y_YY~Tj$kr1=7z&h%JcifWa(c~u$gVUL-SW1)} z%&boDoUPXENWPaH_s#9AkEGSvHw+iS5Nyrr(3If$;3zX(RhM~F-87}vB#`Q71gS;m zB}7aIuT7qk5&=zGuAghnxlsg`Y)38WCH*I literal 8367 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 diff --git a/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/ellipse.em_ex2.png index e3a3a585e8fb38fb84930d38fdee2a938602e45e..3244264aae23833ef7e318faa5d6951c95bbae3a 100644 GIT binary patch literal 6534 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 literal 8367 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 diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.asset.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.asset.png index d2fe2c73b96cc05babc542a9c04ef76f8d23345c..c73024a3e8466eac6de9e2e133e3787c6dd8fac6 100644 GIT binary patch literal 10275 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 Q_M)n6tsL0}ERWOw2fap}6#xJL diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.memory.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.memory.png index d2fe2c73b96cc05babc542a9c04ef76f8d23345c..c73024a3e8466eac6de9e2e133e3787c6dd8fac6 100644 GIT binary patch literal 10275 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 Q_M)n6tsL0}ERWOw2fap}6#xJL diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.natural.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.natural.png index 9e355df1dd1d5681beb2b78e411ed7629ef8b629..510026df7d61288b94d857d0cf82fa4b06a09fb1 100644 GIT binary patch literal 25928 zcmeI5iC@fH{Qp0=$lkPx78zQ!5LZQM!L&%SPBW-xvR7!Lg^U^sEm!3mt}S&7F_UIo zy0SD)ku2A)ETL|;lrR#LRNwPC@6UYd-v8kD{pE2VSNHun=Y5{%b>8QFme0qPG|$&_ z$iR^U34$0h%Zs&uAO`RWqQ8blKV&JY{P7F=t=Gl{o->GoJBIJkfBdp>#;ipe=$BAq zMIu3%5VKg*7i~K7p|n>o^i-7IA^oU9dh7Ysqd<=WJqq+F(4#<)0zC@!DA1!oj{-dk z^eE7yK#v0drxg%Ay^wMEc0upt9O;UFUWt>BBxblBoBqpC5pi9yF)iGLRhM+j$NP9l z$J@}rv!9AX-37g$IR2kjq^EN|3iK$@qd<=W|34{kwoTB2`^zn#Tk^Bx)whaKofl*J zU#{OZs-wLo?q^FJ=Pr6Ky8rV{19^E)$hK$2wzgNKjdJaHcjd44_6D2JnZv5@mLy5h z!`jitGO|!DKkJpmwNr<8zd5L_^?Y1M(__hMWLKR0g-bpcm?(9F>#WdEn+_3!NXt;B zoH<9>7yWcelTS9J=yjEI3_ImJ^tL98JUOUJo~+bGKYj2PktGQyE#4k8d2fXGVgPQJ zZ(e8h;3@|_5@__&Ba3`+6S^N#k(d2L$0$%qLS&vK_0r~{CKP`F%;#U!FjI~IjPY1C zOdbW(M-5Xu8DNSs)G$XVm}pHk%tL^w^`Kz}0L*h5W;_KGov4O6PQmn3!xT|4fuq$h z1EA?m+tf|3&;Yd!)D5LGp^p>PZrxI$M=lIC+*m+aTW3{=g-SQYRrs4}A7)@c;{#Hr zn}cDo+F<(&_?S)09|R!WR5jUPcRWIh1!~>+QviNH-J6+Oc${Ul`uh7ZtLQyFK=(is zpE>F=+)1Gch7yFuMyg#l>d@2z&b zX&1P?r4B#B0p^cj0Ns!WG~{cphI>98Lgf_Qv=hvqDZACt^qGKB&ZA+B#{!IihS3HX z!!DTr0hlW^j1vW;p@!j`156YR^T7*X3TT*2fO$g02q>6KG|W(tx0aqUifsTh&0Vd` zlmh^>OC3;zIlz3@RKwJc1(=U!YGsa4Fab172EY{2nNZLRlyOkcZ(=+J6F@7o17I%C zQo|HcFdQ1D7c?D6=RFpTzKRZAP0Fp6+O6Af(4)IFoC%;*|CJ<7#0i#|4{on=&f!EZ zvc)A7DDgmM7fk^}8ExnV?ds8?J9q{j5E;E-@J+B&Q8_)V@eCa9)+}}Z^wTjKpP^<| zWP=2Q=ppL|N$$WAb%@zgC|7Be0f1sgqxb-d?P&Fg@tJ^fgGR{!6dxMp0EMDOqZ|Vi zZ5qW4Q1rV{rh+O88l^9w^rKO%DU>c%MgvMIjgkT=gJ~2lg`!ELI2?1PZ?q+u=r z%!e)*O&DS$8phBAOZ|B)4Kou|I%=X8UqFR*JPqRuFq^tyf&nI)9>OUAQ#+J~$pe_@ zUg{}Us|7FyG>kt5Gn9sz4KOdeV5q>hqG7b4=?QcMUWWh^&Qv#K0!!v+dTACJg1q!j zkC+80Xk|WvH+m+su`JeeX&-aIK(E~h3% z0Pq9o-du((>hG%#1Caxs%%a(}CZC6562S=d2omc}@XljAy<=1Ch91AC;fmsMs7%>M zHysTLE|1o&7FOI^9U5jDEcS+7Fy;U=vkM0H?gD)pCJJDNcER`p%tspL$sP>zqzlFg zCiA5(7y?3WI1OV6@=l{?jHnMpOCBw_02cGlbS5Nx0mis%2xbAy3mRq$z!as>%9sO; z1Dy$Ldt;bdGaAMpU@p^fDH;SY4zx0YiFlYkThhw(hNe^KrW0ZGYv^8^fLkHGM-%CT z6MAz+Ob1=6?UlOW__RvEl8JIBGNCnu2*M?}^x92?gW&+(!9KWMMOWzRC*T3mqZbT? z8)lVt4QoGqIuz}o#kPgLmGuldQm11H_`PVA2E)pfK?}(jV3Y%0DB6H>jMn4;pqO=` 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 literal 26474 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 diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.network.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.network.png index d2fe2c73b96cc05babc542a9c04ef76f8d23345c..c73024a3e8466eac6de9e2e133e3787c6dd8fac6 100644 GIT binary patch literal 10275 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 Q_M)n6tsL0}ERWOw2fap}6#xJL diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.color_filter.png index 532d4f1e46e5e981f636a3550a41ee353c5dcc67..3138a2bce82d2bc1ee3f5d9ee18a916f05b20d9a 100644 GIT binary patch literal 7599 zcmcIp`$JUK+FpCJl|72i9!Nt)=fX`3J*1>~!_7Dd2;wD2vAm4tr`Rza^OC_>8=0d_ zDo~n|c_Hg~8O5kPi5>L}98%9`$0*~7Wr*NOMARll(T?^#Yc1&OA2|L}^SsadyzhF~ zTJKtW;hB_?+^tLRE`*S7sVTN8ganuf5i{k^K(?=1>%@PA-Zrpx28^& z@y{jC&nKksj8t3V)YUs~et)*$#}{Uu^3SP1SN2&&<5a&o1`My16)T*3#R}%_EMlZ~gV7g{7?zBAz|) z;m--1$JY$|W9d_f```ShWff-YiMH$H^Q|Wr+UH~+ZN8AbG&e8VK4$gI)(2lreN=wG zXVwIbl*RZHE&hrYNhWE*#)x3!Ar)X41D~Rxfq^!FK@5C}f(ipuG!i?SfnI>mg)lH3 z;6Mg8Q;=zzR8m~jW_qhlyGAi4`BOhZ^u<*Lda44CQ=d-MNBAh%M1m%|ic(y@o1l(m zn$BUMmNDw3iJ(R>sy+nNWJX;^sZ7;53e;Fe-7yYSiBb1~TE(RhRgGidH43uyoV@^Y z(QOoDO4aL#V0x1!y$bTrFwG;8D#a zhMHOYF^IpM#UCsyWIGcr8mp1&jV$LFxJNPhs|FL9nNGv2QHYtuLDYH21O^TTID>|Znc#w3k6pJ0hJLUdFL8&ff;_gVPZL7?vBR4gs$)0_&`<5oru z1N9GFRS#-cmi~_xmF$1YpBUvA?m#tPZ}I4hHxnUq2OG$1Iz{^vt3&a70Jkvk0l-cS z%*+GGhrCh-lNCR613))pwgT+LL1-3p&6RNXaCc}HGfg7NJ~zvK5+-?XI4!akAc(OB zHj0_iDv4s1*WLqDVoYZr*yEY~5^58~YDey46nU&5zOkTcoEijbD5Hj9zJqMEAY`8c zD%(uH1E3O4Ma31i2*@=|Qw0Zg0NElV+W_V=uzD>KWS;3XNmdmmeOfA#lsofSQVWpjVLs+`*n2SlFVR)7UN*Op1re(DZ(h=AqLjIv`$VbQ z|8Q^>z_%GV%>*W!5l0Vztf`P`7BD&ZEWov#3C-)=-7ZSSTyq*U7jbYUK(48n+E=S@ zIWR7{x{wHa*%~FY;WL1#Ytwa#V>K&%JyHtgn&nvc>mupYlUvcMW@hr*dQjszH6B#1 z8ovuvu9^`JDpx(PQ%t*9&hd!4hx^|FxRrtB8;O8@jP9kK1z5nqEVQS|tjg+0QOf6< z-vygg-leM%=yTSk$@hv$oz4<*fY~&T&DUb=n^`>iO(e>juLFIu_8lf)i$qqj-9YX| zs#-hs5vaURmZ0Y>=3D442J%lXbyAYcbZly?cN1YdkKap@t9e&AV^*~VJm;Q*7{_z| zSyt-jvGh!6DudV-BCqI_`o$bXanEt^XMpqhK!QXm-op|NT~CC9C|3MaSOp*OMEnp< zSZ2FYuE3q1uB}yNl9lu38M$*=#wJ`;b1mEzS#~z^C|~F zm*jM=c?g;xGLVQ;6wiHsuqn1LE3z+_9)FEU&z80+{SrCFPq)ZUq}9xn)ru z4mL{d7g-7A^HFaWrOsS5ejTV>svuHzm^k%0P+99I^;1FRs`2Ydu9MrB>lB&SzT8c6 zCvh+hAQ#O_)KuQ4RW!=AT>klBlfq6gQoWtz67DllR+{*T%X$c6U!L=45o$>YALzd% zc?FMNn@4ha^CkB%rey9vTBp?VnR6@^rB$5Tgxa6t#XBJ@wd~SFN}>g^4{Jo^Zj|Z> z;Qo>*_2#SfL&a3hnI;d(9mm}lNpc+5Oo>qIt=tC{8PpC&srBg`Tp>#5I2ek_3E=}7 zXIASaZhuQw;(60?#EDV?qki|`hIdTP)YkXwM%LF)t{GW)@NwnsVMDS{+$Sl~bh&=_ zU`oyI={3gII^n|c=j^-h{PNF3J2c;Dnq2b8hCKE5DDT5d*SxP+=g5n(w)*~NXvm9{ zmGVE)<)4-8Qc_%HI68;Xi6~rE6^Mf`&0unF`kgsU5U2m%Tc`A=w~4RObc)&>GekG* z(jCqrrWkhbITD_LDbL(R=FXtQ`~b_-l*;IP3IlSF$FcdqX& zR1W@~d5Kx&eZ1YfuOy#mGjuawFM9Ol>&e`geiuuxn9|dJrzVT;0krt-nTB2eOI-k& zW=i4Sx}y@CWMylFHETkoUnqSn21a5f>0}PdQRe|Xl znyMInj)jK7zszK<-O#3Wk`+1JdJBttxH+M_O@1N7SSAZ%uI0G*$1A1Ci z(-!$P%;dGTG{TXn1jjRI>mJ4b^^`n@AZDT{RhEWfE$&=L^~;fXl1>Try=kx{e0R}A z^{)jR%VGsFFLQtu`h8A8|H@S8N8{Xi+LqszwQxOE3rln1&>J^oxf}IZwUG{BY*pYS z+~wBAy-2YUG&3yofYoU9B@5m}9vP>p=Ouh?Y{Su28$^TZ@~LZX8<}lZ9nSD%1c>fW z^JoYte~0AiHipt{ebn(ru+g^@hwr=(Wo&KfH1uZ_wvk&{2$pb`nZ{^}(U%8W)Nne0 zfG#lbYUt~9rQL?>ubP|MmtM->xl475aSYa`pS8}@Hyp7HQZ>E{>XFwnUJEjGG> zXDjC6Re{ymVPDJ&X1&GV#qbS=ITW|JPdVonc8|g6TOi4k?E8|CezI#+io0c^i@XT=xPXpa^Oxo|zfN!c;=;klQ(QAMTyf!6^m5-Vd`xt&N?vZc`btAUQ^T^`0{Jw= z_+FdS{^&*fiP`q0E9wU0DP%>sN`^)x42`s&L(LAuXn{9=z-Nxx zZ&=id`l>PbA@~h1*U%rBerJ^b8FvlpMf?cctLpTmY1lDBP$E9FQd~ic?t$lvg-KU+ zx_ZGTYQm>tSgI?1?q}5Ggvn5Kdg=n^g|Ey}sw;ibU1}`@;Z^tn&d>~#*bj8d) zLQOxxG_dOQlyTH69kDK%61HwZSp$mk7E?aX6*KTzYgJ$@Zd=YI*QD3547BSQd$93% zL?kst3S!JemvciMwJgHDe^EnT&RwizAsvCv1{=fX-ll=>;>sW4uh8A2rWgb|YcTGZ zdxM$=!}Nr|qSI&0gh8EEjB(W?pk9XZ#U#3_Cmp1`wS{ z(>E{;^jCDps~}8xufiKxOH(aO1dBrF(T`Z&A9}c3i0MhL>aS-ZTYP7l=wq0$1RIK! zUzvALxYci8NM5BIc@)ffMGB9I*UX-UoQdv)Z(e;$8uP561~iS^_|xIR(0 z|KWW5ntk`X@ApRATUXg1Reb7wqiuZ6FFATKrJ+mD*iA>hb*|@IH+dgs-X0ipBh~&W z+5YH%|8o1$jYjX~2a9X;BVQKt@iB5BUm5ZFKz zf9n0)t9`rTg)k)8+|u%XTYOvVLi^>OW*^@AVj~Te83mgP^Ymj5KHMq`(|+tG$3DB% zT3fyO;74;38W;ZU*Yf7ZIyZS5`|Pew?o%F-(Ea57L(PqI_CK8b!2~ka*{N&st{a(g z|FR@_y|3R{Rx|9fH~Z6yC~dB+ICK{GxaYq(U6H)&O@;RG%yse=YiVO+{n1_19_>W9 zE8XO>u%*`czi;+FTxNgt&AQ$GABK4o{MWrlhy5o=!>%ifFjVU9(FP`_V_wb%o5SXQ zMSGX;TNvXEm7}w1dlvTo+c2UmPJjN`*stiQo6dWet}gEWwmVJ=mJK=uB^DTmom>mO{+4 z@(b5{6ce7UYBl-dJ8kj1WPI}D>BwOIt76<2VpgZ)^=PbR{&Ps{4R7vq7FOY1Zk5Hl9hWnY;-KEimaCSA7e`v8+D!=at~`80TP?z% zZxdW?qFYN@q&o^vYC$g* z!E^&&Ct&hbhTB|+(%j@#j5x0=^2FRP!2qHZ9Bg^mAII^cmTrkapBm;->LXEB%TD+> zpM=Q--g(@E0`&&7YR8Hha1)oOyca#VN0TpK+J`_p#=CtD2vjw+K=D@`v*En~dP_cl zX(mj2U=n-dR#Vc$Aa+F#8?v5&!oR@7Q5ti#61>GpZl4vrdFOC>sGugK6w_1%QwvNY zOnVBbsm>BB4Nprzj1zlWzyk2YWSdM`Jf=yZ5lu$Z?T3Z;iLtO>L2 zmv6LVSoW8$e`+7&x;M)D_|NxymXCA$d^0P=`ouTvt>+65o}6JfUZ>o?T{~ZuBrR~w z`_0K;d0+p?`}i2xr&8r0OssRuLHU8rzUC+wa8QAWrS=mKjx_f{f2n(+zW0TX9f~Mv zn>~uvql9WisE@I@Ct0LQ{4wENlvR$jnu-Bh7-$7Jh=WD=3x>{M?Qan0;@$qA`P5y; zV|~_mw=&+X;<~LaXFekS05Q}|g-V9tS$}~|e%~gqK!d2=BAd6!xfyVOFU0H)HseE0 za6HMJR$(L5Zen(Pp5eko{TQ+Y0p;T7KdOXo-S9qvDf!c*pm!P4fvrK(> z{-wt*s#}ig78fvoEY);Y=Q8>its`v6X{bZ`1UkAh+}P+DiaMu(8I#CB+)#XjIfx<0 zBry<=C%#uWh>$U<6pY0muY8{{@HuG4FirAb{-+v$)$duj=jg5Slu{ZhH7Ub(*y>pO Ef3wSbq5uE@ literal 8160 zcmcIp`9l-e_P;Yk83av2L=cxOBm@N&H$;UPLJ-34@+!4dW3kG!E~r#lQWzv?Koks$ zs32HtYd1-&Pw@#FDOJ;2gtmTNs)!+Om5NDK!jtOv%pK|X`wu*RVJ7FC&-t8l?>+b4 zGsVe?(L;y$4nYVF)x@ahBjh4Nh)kgd!!P?cZOMRt#K!s2Ds-%M^dorTY*c9$Qt+pv zmKzWfmT1%w3$v>KxSe#ler3%y`<0oWc@!=5RHjwWTR%-aPas`;xqO~pOYJ-)fq%{>$~NwXsvgW)1;eMthTiseI1)?IY8yV`B!&hc9SboCS8&B#5;~ig%6ts9dp+9 z8n5VPWq;GlOHZJYDaal%&szAo8xK`V6#=oj;BbO8Z)kCiD&|&-lqjXdSr=eGKZQe~ zA9=#zGDS)WBD8MS!jD^Af8>i$e3CACw^OSjIrQhn+!9Y=P#ledCt%Pc0QxBgHH86a zCI&Tt`4ns(CRL)UtqeS|hyqO!o;rO2^biKkZ~=Q0wr?l`fEX5_03Ji} ztma7fKa%V?aI<%TLGv z4IJ%q(l3Dj?PBhDPoZfj$QNPx>S!9Z?ZEcGd5Tb`SaCE)XJ%B-2pA}>5JG*IwGu+8 zYg=5sin-VKLVVsBpgReMYNkCR%IfkT2x@gK_LT;X&N*PevJe~e++XU*vCi|M>RUL4k%d*jUWauL5UbI+l@yT z;XDS$9KuPCmcZ1%0?>FC^g{qG zW(OyPAcMzYP#6UPPA#nl#c0Mm8V2ZUjNUmO6y305Ry883XzVBzGUI_U(OQUOus_2I zodWlTER-A`UD(GoibtQvSvG$Iuu2woIPl|Pei@7hggt~pC;=>ND`a^H9ws^t0AP_q zsGajkPMrv=ro%cJ?uXre4RRHh*U1PnS&tc>@CSRG3VH&_Td`al2=;#1{<;wn4`C5O zuqQ!v7ONT#sx>%4<|V*&Cu@}iT;-Uni5UwQ4Db*Ltd7S3IS}k9HrRt;HJ9bWs1jK9 zsFFt0*cAN(9BgIfo&?#(4%-H*Py&`~ z09d)PT%{zZ6N(Bf_2B(ypk|gTb;-Z>!ke!*kCsE>d)_3ieZ9jbZ`y{cRW!N<3uw0! zZH08N#dQlsf{SaoLeh6(zFagg#n3z)TzKIM6%5tjX*sTT@liB_99BBfr+!NM9u3m|}<)2t;O>;82UTIV2|qDi9RQAV^^xpQ(`a`xH+L6$pmeG@KxV zaH&I;0Q!gpHFBun=@>KxKtE+c;{bFw3z|)Gs#s7SLB`L;F=fTj=ocIaI>r;3hht6p zB6!Nep3Kt$lx5mEnB@3C$plgv?gZ%p$%dq4k?;r$0v4shVMlVPM9Hc8pRhWXRxlea;UZN@Nun^>>ifO-aJ7;Ta& z>33NNvmtNy*=)cJ~Sc{*}QrHYBb(2(O`*^ zKFm5OViUav!* zYVgj2x)W$K?60s#pd1*c$t(cW@YONcSDl<7N3mQUg6d#abv#ehR>gAlB00V+>QObV z^kcbRrFiKqfjT%sdB2gz(&j;L>;<9>b~mSg=TO!7+=R3ol9PxxX%sw!Afe_m8S*Jc z1%9|%qtdywna==}ZORMmyH#kbf8IeX>bG6BE&WK*7ttebySbprRrw*qA$s-|*||PZ z-@=|T8BaxhmfJRWYvJ3cY4ZdY;9y)H9EMcG?DiyM&x;Q79lj_7?@x!v*dwM}3t_)$ zfFq>D-VW8#*M2^hLxsU2-{nk)y0*iqolbI&VS+ayIevtq03v zqJ?6`P3*Qalhl7+%*zo7*WgK(F_vh4rly(90}p{LAcvdfz&dqYP% ziqzjL=C%I)KAYr7RG~G_^hjn%XfV%;(Psn=!2NdSw_LQ){>b)yu4UyD>7AaYqJIy# z?vA9*UbTr!bTj+DqVCSJ9v+Gp%!@9spoR{J ztO0kw`YY@B{3*i*;Getk(qr_$4w!4gBwJ`l}NLwU}Cd1(}Fo~w=-Gr;zO zpHdqs`DD%jT$(489RAOLvt94TyIw%us2yPc4ZIgqH~yB};e8i%ZRH1 zdcqIq`UqcJ7g%7nmp<8RJXdQI%Cd8NCX^evRlD4&OsnV57xp-_ntChSKbqcWE41BF z#N=&~_vJVB(oTA2-(b$HKNBwX!D3&Upvac@&Cnc-HM&~<++1;LPRuLygMY%7Xl~?C z!$qn@$Xs@qVi>a;xK#%hnd(q|TFqSDiH!?%QcI1kE5EwYX#4Etq_lrnUG6_1$)W~* z*gj|agOkpz%QK8&HMTLo)xYC7jo;Pcy1J8=t+4xG8AjM{ldZ95#Z*T5O!y-%>(PDafK z&@8t*ToBoeM$jEit1eXkpa! zPSgr&8^W0kPMyc7od>j3IRCWyVKoMAB%n5gnQFtX8}FQX4VfWyPv_>QuCzwBeZl_L#hE6&lca=U}Ok{;0#Jx(G8vkz{#PE`h44}Wq5f;C=z*h>hu zD{+vQ*y`eQ{uwuoo?s|D6vSs-51otPnp{8mp7^_tv@~}s^Brv%P1a!|9*P+v)1QB1w!c|isT;2IG zqxS>8te)T6TEd8)B=!*K9lo&Jc0hAbv!T~e``3*c+eWKP%8kj~IQp)EyXo03>6`?| z#U$tH+S{5}`<&>l2VOziS=Pc~9eZv0wjFaeUTb5q5RbVQ;r z;9fO+NkU$@N>LdM_w(K0njcCNyL37#l`y>GxG#O6baJY;A|k7l zdVBsooD!xTGhKaY{#?x3?Q;(yUHBZCBcBa*2 zC_j|ojfKS^+(nK2`7h}t|Gte)+g3;E(P3yKuH=a$_bHfDK`?YqGW_{d^zU0?A4XRJ z+}%+AbLDm>{)PTZG*POGT^z!wChtK+x>CP;!yF5@qW?xmWR5_rjDkKLpFe+#6GA3n zs-mIA<;Pks4h3~^o*u8y6e|t_FkEkFIH(LcXOe6^TY2fj^w{CRbrEZzSL6td-(EAn~nA7_V*XAtk|2g zj<^pEwOM>|G++4g<%)iZ->E-`>uqOJ{NkQ$J6zZlgz4n5svP`3=8Mf=L!QkgV3h(^YvDV_;6>9^dAn_JAJ_wyi#O+TQRkE^{*#(2 zbrPsR>#`q4YnDKfzrF2X?7`O?9PvG3Q{|lVFT$5n<7@o1S!DDBNgadQ&_)SLgnWxwU&8FaQc0kF_n8+vHA*mI=1%PNT zhyq}y&=&wNJxXuh0-Pnj5Ki56KDiy{ocrlu(0hk3HbGC(R5cYKOpFN7-Dkm3$~6~6 z2t-Hy7|{$q^n5^+tAf2Whc6C>j-07s6zoK82dDxKd_o#q#tcS+Lhr>O1kylPt~>#K*0uGd6yu$wmz9ee&STX_As^=^G%zWFs2 z|H@nl*QKgn#q~_cD2k&z;ENDGz}%I-J`JEMy%}0+=v0o6IDfXKH)mZzpqlddVTK5e zzIS(q_)ff|0GJKAqc>}TQRok!Rd_GW@A7oiGMcF>Z7_UPIsDPYzPpbta6mo9A}XPR zn=NOJjW3rtR7Nf|Di&ppaUa|XDs1&|?d8_)`7FhmVs_D3$OJz(2rmgoqRrBtA z6yEpnfl>HkEZGQ!qEjN#f2@Y90DOX}q7DV{$w83U{X8*T4wwd{aw;o_8J`}jPu@)x zNFbJ@E1R%9B*SIv`f zpo5C8@4;5HVS02YVh3a3)6~B)0c{!ptW{G{#k}j~h^Pz1Rw2OUA*(u+`QpZMg}I@G zUID~14NwE3Fw|V&de6XcZ3C`#Qfxnwk;h@VJ7X_kV(p9vR}Sndv=F#b7^)i9V6X?a zg3dJZDZyN$p=^0XV*o$qUWpQ)pSEqQmkSddf8aUR5x2w{>v+-;SvLjJzV$iGx6h0Z zDs)HLDYh2&A)oyiY6eVwk0cEB0dV$rPGn*VDqh5pNb bLHA#~6qjawu~(cTXIyEb64l34+AaSJI=J9p diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.ltr.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.ltr.png index 962179bceb31c8941d19bfe5f8afa2e8f298c991..13f1aa453c9e6c1030dcc2927330ce88ca28175b 100644 GIT binary patch literal 3389 zcmeH|`(Mj@9LGOfIZY3=ZzQK=tJO*&UF6!DS*?pQ^e9BA)I;t`7nLSqlUX&CqN0Nw zq;W(F9W+}~nx%^rl}jmEt-EyI-+ny*0^eV@@ALEeyf3fMh`5gQ2at@2guU=X*uRFuLiv?5+u=oXKg-RV1Wzm}h>y^u&u;AH-cjef-c==? z*D`vp>b6^2eCOS+3IoZdOU?ngHK7^_IZ=GctF?Qwbj_?16n-l5p4|trW!^doU;G=$ zg#nneWvaVac_f~9!{I@2Pp;-g$I}jC&y4U$icZ%JdU5>)N>y*gvZ~&L?~Ydu41bCa zrW2u#-_LIcesKqQVIKX<4%r&@VW{zgu+rl>!?uI=_xtaPj<1-iG_M=Ik2lC=fJu2e z1UNF&TzK&RC`Ltyxitd@c%j46-i3$A+lSAwq^Ut4D^kvdXx9_BSP(UN6-NFWHo3l5 z3&uy@ysRl>6`~m#z6D68{BXJEDBr@C@o22J`_TQhvRP=wR4NK`iA4p51R|6EObb0E zQ_&>PSoF$@KrH0~7{$R#0M-DQ0FD4qgJQk~OxXJdNAb_ z4s@xgQ9OvKJD|W_0v*&tWuiJ3DD**L1d3=-?9`>8HcuWRV=WrI01_Di$D3YY&OjEa zh>&NaA~35pNlZ_O;If>Dl*xl=i#LFmd;o3$_yCl+0)X@|Od+TUrT3v6J%};GoT!=e z1cJ7LpWdfII&&hKrwv(8LbF^O$hwctM3!u5t2LEhpH4fJL6pDnGDwHH==6-p16R6cmy6}kJz1}fpC6GXP%#uq)Uy2X&BNLi`1 zn<710wyOx-DgOTwEmCejx(w`v17P!q5|n z!>dhQ6cgUhX8*9M#lVb85DMB1jA4*Sf0;gLy9+I#sKsCrari{?#THt$gCc5CYMp*G2VBiF zg(;Y$v#dZ>eI^n@^U7hx^lk?x2I)~YMLXjXd)&mgF0OAta$sBnn@ca8lh_85_2ZHW zAXyzEs?2gVnZ92r%HK)@vz0FUm0Bn{+l~{WKQg+qSykQVpLkwm-*l4Sp5+7!7g{!z zj2tG>^FO=}RDz8o%vq>| z!$SqLlSoDC;_U41joah%t9LqQ*e}eEZJaAq=Rg<=e#DLmlKb~$4TXH}IeJ_iY~>Ka z7vj2 zPcMANF>t%VvDlPIPuKWGl2ggvF2&ICRKYb@v7qk9lV}D1u5@K% zXs0k!zOlsc^-_i&W{mpq8=%??yIm4h64#};p6x}y(iGE^VjmdSu|l=`>(qUB`mWt~ zlvuwJ`&9XvXyy!Sl2CEOJl0u#(Y@wJgQ8KlK-+*%ffAd6p>=NuF0adsp8qB@=8q;_ zV^jmD_=|juBkO5V_4m~_H#QFs`UZAf+~d+ynnnv|7^K+S)#Exd(A5{w?)2(=J^uc} zul>k~U-plKrZGC~hV=4n9*M|Xj0ic_w=N70uXQAI&usF?4!@UEK z&d}xDvGgV@jL4k}*W2N6FG{9}FlO^`GgQ3~1PWqoO< xCK6HMckSs2acBJRI|1K|-_LIcet8GfUmnXMJEu?!GMD3CxH)^V^I2OG{sTz&_wxV% literal 3722 zcmeHI2~$(a7VaBRBQ6j?6ylJOuu4jF5Mfx7h=H)o1dM_(Do~0KWyVpA$`&vxG68{r zvdE5r%R>zswh;#5y%8cJAS$42BMP!hMZknbc_-HVi)YuZx^=$(&gs+N={_Cj$ziWi z(^EqTt#Nf>aS>7>BZTw8F9#&+%=r`W!+2b_BNDf690fy_=jgfz4}*^n6e6^Cn=5O_ zp0J$BzI_S%Pk&c0`#baXFMBs%U(QM(Yr2`nJakz(AMo#(VixJgS1ZodU&>$|d=%g) z+}iPIpX2$I^>HbthuxpknXDJ&YXW0qx{Dr#wNl6J*Q#Kn=gsMTxtVq96RGKyJrD9; zTMkc$_vZ4V>!P~((+o>343haazA5m3t^o7?;o;to`}EL z(AUT?<|eC{jau)%5mb>`wP^ki$Za(g~qJXC&6t%Z|`S)Ap*5-ms#M6~{l&kB> zx2MvPS_>G*YK}#g=;vfEh!v>d08Uj<*<0!0wNw)}A@$WE^7PE;C|1b6hmQDK(kYjL zLj_K{P#s0=5TFy@Z&d_-1Tvzz^U*VRn6cC(p_wd%y(xdR0(~YkkbtI>KIO-09A0R1%u!bu1Q8l#&q;J8)2qqGOV7A*AQqz%+>J#=qiDg z05mz!xe-6{(FqEM^VGZ`6v?hGWhu}b7KBkrjl)NthOltG5`ge(ZU87V5h#J7Lt&WO4O5xy!QI~( z*_+bL7b-gAxWyN(igx#$`7vl!_*0bv9*~*wnj~Vr&HP1Y>O-x$oN^0RQAj?Nak(e} z(`Kc-r8Zm9$K;dM)4hzLEvp3j8f3K0^Qt0j@s%-b>!ecPabvoqQGF-uX*I}#N;#$b zu6`Fe-A`-CU$DKkpt$wvXqi@=x&WsIzU^{66l9PoK-w-#6vJ8?h<*VyzWT2iR$!a_ zebVSqXwt^&n|+Euj*ed=HmpFCpxCmRv6*Vf{fa!4WH8kr^?x|u{@{$bT1hG5Ms0x| zA5+pQ4%yxgU2kweD)kBC^-$mpB|z+Zt<>T&#jEnk$1T362Tjc8ZXH0jO2x#V@uT*1 z?vp%@S(I@z<TV8rZA^i_atT!p6XSN^u@{2$Nx3a#Zp4 z$u^NOGc~9*!@eXn4M&7|Aa4z*7OQomL2Z)g#zZ%*p+w(F z2+Cpr2XYdVqZ_2p`>1!PcEkwP1(!kBokygny#GGEP;xxTcd;;E*8cLaa!ONIcLs-M z+Iaq15ygGKbSH{#$SHjWJz5Io? zrD!r8L4HP7A^n3Ngo>R@CRV|bXRR&o4_k|(md>wX*i|h}BcCQ!JkxcuH>X8Z>Nh(l z468i5Td$(FE_ZGr<#XBirXsB_FK-X~g#nMHk2zmjR06KUc`)ki!n-DRXL~rz&$oYG z==5?nDIydRQpBbCSEA4M-?h9QNmmy*Dp&8yP%?=gUlvKc6`%am5;-g?F;V;VbBi)! zp?9QT3`&J-UQk82tXJV+r{8aBZCA6Mn3h1Oqe#*V*Q-H^uOJ#4-6_@(*^lHFC)vTOG68jSI(Z+6w(L z6Xu?ThtTX8I)^BF&5J!sA7zg#8lo6>tRD_#EVe}P%8u{P@{*===q0;I4h$VBe8zOb zbcfZhw#I#VCXOgJA7KH$H!mgc@y|IsdaaaXUwyXiy6-krgY z8thfPVNX?-=o;+Kt~~Ivh=B>#K_ffiZQ|@wV$oVR^CEI>E9t-=ffH|u2Pfh!oX-rz z3Y$c%z>d79?u2o3>LrVK4Z#51up_RPj$b~#eCJ_(L;N7{tt7ihGGF47c0W3Czd0l% zf_fdcvksarJ5Ktu?ECQlh@H20K9TcJxyPW@pfNMj@72c-b{(PCH&Y!lU$6*pp`hbT z_RJ;D{k4jepQKHJhXdX>+v)!{X5q1~4@qmB2I^KmQAq%-fm(k6;AbU}h&er;%MRMy za#SBVfPN#n&~!feaJ0HQ$E~2~`Zm5P@J#_w;9234ieOfI?;?(PP$`J3 L6Ne>s3^@NkGXavB diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.png index d2fe2c73b96cc05babc542a9c04ef76f8d23345c..c73024a3e8466eac6de9e2e133e3787c6dd8fac6 100644 GIT binary patch literal 10275 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 Q_M)n6tsL0}ERWOw2fap}6#xJL diff --git a/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.rtl.png b/third_party/packages/flutter_svg/test/golden_widget/flutter_logo.string.rtl.png index 9355a72d7429bdf5cb3fcd42ea55bbb14ac3b3a7..626ffb7fd58574041908d1c5555b7de5dc284f68 100644 GIT binary patch literal 3389 zcmeH|`(M*#6vxkZkW4UOpn{|^Hg0KZSYZjwIR|5SftT(j-o=~>ge@;|3-B9J4hZFD z$mC{IT!AQ3k|Ihv7^FB%kYPZ|O>kTqg3d9d^X+lx0C-dA&))!G!UUjgrq4hki%k3+e~7~y1Ux9aH-7+MOb_#fB04^Cbg>j*)>9#W zl_)xIs6(BaXSP748+qTWs-ok-U5D}?e(?Q7-V$z-SQITSZ`vp+uyNUDx<=CF)Y(49 zidMXBdcXQ-r-)isipV)2tNH7rWU1%1eWP;IGd|g#S?gp+q8zP;N?ohk@*UOB?|Q4B z$95c3zclp4>~p2zI;Nj#2ma>{kcZY-F1=7J=g>&6>jz)-4+{L^`Ev$ij6GV0u0}Be zkB>UYIcSo?ioh!~+mFQm-!PZ}+}$!9Aj1uH7Rzrqh8c2sb(!McyBWFrE!t=y?le>K z?t-0LclbXTOa6D{VPi`z?+Vzn;aS9CDC{Fu3Vk`2@Olw%i=71&* z2&Qe93AvMQ4d1$Qp#LNgA?^qg5X_)J4gw~ERR|0S?6ZL=T8dydf>;WCkH8JVy9gp( zI8dL0Qv?*iEW^S$NdJ(a)m%}UL5wvMBAif>3dCbeRCuGpGuaA8UAZ8o>j_u>2#VO@0}U<>*ns<-!b&UYk7i8I@A>c;hwupsd{3! zsZis;$EiVER^_7mP7m&87ek0_|1DkYKQ`BEOBZKG_YG#W<(U6zLTzJ_vr^@$G~*87 z+DF~{(p=FJYPG^VpA}!SSg+HyQav#DqmX|n%^C*@9Bk;Zal-NvagNRJAMkK-Z`d%w z<)ko4Y6a%#Y(Rv9&OjqbT-4RCSmGxA=4%{B#>(T;D8r+-vh|>tj}{T}zV$)63~#$I z@A<;P)az_?Rg{SiNeftFjlTbPFAUAyJJXspZ}Z??PB~F_okdAxC^>b2?W{$~3QE#T zNv^SZqbMn*B+ZE^QB(-_2RbuSuht1#FEP;UaQVm2OrTz!E3ZhMOeh}F_s1^f-4i%S z{FF!3g}8CQbj_s0=^4jQlqD2mDdZ!(34Hzx-TjtNsn@Moq}a}JN0l#nqF9U-9L`k< zTC4xfNG+Y|_^4AOrGW+5)>cq+k-Tjk( zhR{dhdA3e4j%Qhu?VGgSFr>a0Rrd4B*3c`gb+XfeoZ;{NVuLWu3F?a7=KD{ys$W+e zes$}%uwu?zUP?i*!@4=g-`o~ko zTQ|LOroLe2hWa|#ZtG&FIX{%ot9-Dj^xU>?K1Ml)Sqfs4(|cTr9%@N zN*lfHwT(U|l4NT#9B=Vh&lFo6ql=y}XeGmvcw>pjc++xr%;P(Z_Z`#xWw{Zkdxi&R zY_L6}?Ulv(UB=oAW4}#a2u$$FtTtmESlfHqg$F-j+iA*aUGMYi$e!5G!q~Zw#?MC{ zqXq;xP+9rf*daM5T-Lm@_+>y6h_IW5F!LX%`u5ZuT|1IPClr?0@M`#Un8Z}Ge3PIF z8+uI>f@S!?27Xz8vmNoH&kYRVA)rF(oeay-lB8 Hki>rg9Qpw3 literal 3721 zcmeHI`#;qA8vo3g*2uOP$~9wVD6K8IlqJT{l%b4El8z%@hK6)eM7hq{qjr$SoUDr3 zP$pd|ij^~(3bpQ(%Dv<=a%smU<9?p$wg1KO`QiJ0J=f3kyr0V_*`4XMX0^_0gwPsi z2Hg`O1p|bzKKSo|lNI$#IQ%dXo=%Rauu*Rq2wa4tvlkvt96pGP&<_^QbO*09g0XJD z3;zt(7E6cfN7)CcE^D}24u%=-coCm4_1sg*Ir-3)2bx&Eu00`H?cYkI8ZY&y1j23Qa%#ccP^jgm=Tay6?NB}EbK0>u$YW_#taRu_`S&@c5or#az#Yr z*?b36Bo6N=W-Vp&Tjy*K3%TXsp>)7ZnKO=8MKLDA zqm%Uur5UaFtz8AaN0Ma77|#p9H1DXB@`L&8xVTwfG_zsAQiZcc3DkGSp=K-wOPi@u zM4Jf)D01Vn?EOY6N~z0k#z?wQA1gAl;qu{v603+TMHG8y7@Wr^2J5ty1)n~rCL#}D#fouo5O0H=ma8)q=ODYilLc8 zu#GNoy9pM@S(~haVw^cBe0QG$=a9Mq5@gCyE)g;=P$ie zt_qqU(GV!~@8+NkfeabAVR5-tkjYtaVPr%_S~v{W-4QGu074@QFbsh~E`RCdQUvBq zLmF}kRF#_PEBmh{A^`*3h;#c`GwVlw7&2GkJXbY9JDG9lK^9(>L)t(^KF4r)aXO@N zZ#NbffQP8PO)%K4L4`fDtyg3y;IWSO6c$Z2w(aoOsW>AoR@|4leZbruvfQu{T=j`$ zcqvAF$B2f`b09%u9G>oX!lEpE%0+)f> zg!`wjYlNQcmb|&>_qsh$e-cRq2xFXnz3S!QOI|`@3-^Q*b>moSOGuXql<^tG2d(nR zm%Tcb#+wtBL|>aP&^wH2Rsf*TYIP!SeJ2^xN(O*~x~rVt${YX|Zvz@y{b68uO=<+I zsP~dk7U8dWnn-M;9*ZJNG426iYcQuz0$B9`7woWqQod$2fDUM_dVL|CJ6hh;WhRon z<-dq7(l9B7EU4ZNlkpV@JiLWV9yD4kti_%h$8 zfS~<7)rVZilezX&iJmt~zm!?1$0jaHX12VadL1!uufl2D3sdlB{C@j$S;w}VG%kD2 zO6bu!lYR9m(RyoHp1I9Qzu>Vd3*th*Y2$FOE%M$0J_F;^(%;+?E%j51^z9xb?hKAJ z*D=#k8=jl99*!RBwkatcnncF(X*?C5EZ6*6)wE=m_?LKpyM%68+``~*UN)~F9eF%N z$J4Cknd*{mdvsQe*>KyDBI=TO zWKwa)|Dd)uFC$G5K5?=()#`5@y?6VQ@?*w+8?*1SN(^6K+y3f|rS}EiC%EWO*g?!z z54m{2sZ<2uHCmWS`Cdhf(;w%T&W?W2z07WtGCb^zsGdO{ zJid<$%VSSLO)?&1tb)OcLmv}Jo7%!+^`EepTgu}v2e&Dr*5yc$zk z?XwRx)LVQ$_Fe=VMX=GnuR*$9`RKt=-igtioY=9}dp4zU6CP=ElG%rrOZ=a=OCS2& zDol;p-ZNpVhTXaVYth8UFDZYn^|`W2!dP>QLab@Solk0ETQ1gggk3KkSNF(%V*8mg zR5NcMQ?|bWf3>6d({=qtC3KGr%eKVE%+WJG^y9gluK19Tl0GArX0IyiKpeGL*=pC` z1Y`2uuR(`W-uq}DoD<@*z}N+h9xeAI!PC=&t%AXC zi;U9~x|-|n{uO3z_k2{Lg~5~Ec*7C{Qc&lm9v7t3IgbnWO?v~dbq!`#8r-l^DZX6 J&@teb{{dcRr>y`0 diff --git a/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex.png b/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex.png index 78fa8e1206e717fe141cdfd8facdcdc8476769ab..03519b9cd0df80b88d6465830d6bf3ffb1be145c 100644 GIT binary patch delta 1999 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 DuIGS@ diff --git a/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex2.png b/third_party/packages/flutter_svg/test/golden_widget/rect.em_ex2.png index 78fa8e1206e717fe141cdfd8facdcdc8476769ab..03519b9cd0df80b88d6465830d6bf3ffb1be145c 100644 GIT binary patch delta 1999 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 DuIGS@ diff --git a/third_party/packages/flutter_svg/test/golden_widget/stick_figure.withclipping.png b/third_party/packages/flutter_svg/test/golden_widget/stick_figure.withclipping.png index daa068799c5b885cd564e9c9808f8cdf84a4e783..e6039db89e746335a814ce54e205e33d912f7a78 100644 GIT binary patch literal 20024 zcmeI4dpuNWAHb*bM!l7$PxnMSDn?2dxrEULlM!knw7Ikug%XCuFg9BzDs85;384uy zxkSil45jR5b6HJp>pE|_jA2}cVO-wxoHMr1{=1*uKX&(=e;nueo!|33-{18y^Kt#K z4RP_pwF@yA%wo%fW@HRzfg1*+sH8L>dh&ulp#c4u<4-2;$7EHh^gzET`0uy0Q-Ut4 z(rG#dvjJmiw$Co;VPDytInZeM?dj}(C7=zxPy#3clmJQqC4dq@37`Z}0w@8L07?KQ zfD-se69{iCPP$t#wEfm=AJR(fcfQ~6U-ho$YP*Gd|D&SsS}iDbC(1^aP>$v%6wT8q z%i?sWh_tRM?I|}e)g~`m-QnhbQhQC>nQmc{;92#&&W=@s)cQzejej&TbaN;HlmJQq zC4dq@37`Z}0w@8Lz`u^b-gBO3l)C-|j8vYR}$>Z=ADo_I~dj%ztO^H&}-MXZHT~#=nz# zT#9B?E_^~fybswYogT(>9R(j=W3&#!+bXpk5R128dwsHT7kHY!0fAte-*Is@kw`pK z4W2$qL6A-6R16iQLnB<5?7lT%#O^)}DqQWOP@<)FGE}`}!tNuCk!1zz-%HA_kB*3l z$n|)vqM|aXQS!hhEi-o%ynEPLlBEep&2C=cN{phIrfdf zwyx(nzlZYnj0hO^5$EL`V43h6g$}C(g9fcU8qLHr_~PbR%aElZTg=SK(tz@Q(2^1kx{@mJ3^O zqqxpEcAiBlwmQi)#-lp%uDGU#eu_#a`NmvZl+n$DaWBbRS+pbBp zO0eIUpLpwNn?$(jp0}p5vQodK?exy;wP%-WXlS%WW#K+|@F{y*M3g;(b!|(5f-Ec? zAQy$xI^|LH^m<{fx8A99=kT~~f~Rc#)0t17Qm2XsrMdB1QJr3=0|EnArq*gkrAS*9 zI#z)9$Mz$;PH<9s=3-IqGj_4EFt5>jU~+QORxYs*k>K91aMV#x**!BZSvf6g!#*>O z$r?3BETxZl95ZP6^ZSAPFp4*>%3wb%aN81!K4e@)7YrZp6w66)RYUR+wZFRkM% z1)KSH3YDwMb}DfGvwGtV6R)VKN1Ntp#`>t&XkO7U->~CK^3DxgUo}JoUt8O>(xLO< zR*dznlIo5kemcu)#x!6yIfo}Id`Zs1%f4jTZp$xO_>sn(FPZv}z7S;h;K>ihcJm-a zrKfO+Yo?OxC8laDu$cB88P_fVei%JS?nZ^cl!Q-m<+514pZoj!3&*KpyH5LnVexJk zc$Mw7>B5Nsed-GA5z-GI0;Yn~6Txu%S99SCW4y5P(~vRl7H@F;#ncio5)*~}4*XoS zt&8et&zH%vT?6dx1CEj|-y?HcJrLzfb>Ohv{({Bgq$+0jhn7T1b)#}vTB%B4l|gn0 zuGMx`<0%Zk=Na`v$+@wR!fi~IPY-oQ8`Z!B#%4%fF4JBaok|ZX$*{r?H+qjI%i;^d zYMp{x`vHUSvIWRY^e5*wr`Dz$k;N^PJ)z_IZBH26aGfnr2nGf(ydSs^<+p*{TS}M} z=Va;NI&-%AsCSNhn?#gN>2=m=z6vx26E7km6LTvK)rjRz9zDiP%2Z9_sO+*w&r=gP z-OpD?$h+*e-j%^(83l{2Nj)^4hmWjSKc2&4)mvb}blW!~79aIAR&~8c)=SQ4=6gy! zQWbeM(_y=!F78x~(J5?E2a{5DVP*%3@l5V>_ zsVB`sxwSs=(u%=z%R9I-Amo-NpZSM}!{+!i!#KVum`ez~c)(UvREWhg8L1D4j~#FU zqT;P`eP&hT2Dn6@Uh=y)1&~7h`1b?`nUl=!5={ZQoTG@Gw{x9tEWP{IT&jM8jcfl< z)#&7<1ZHJ{G7xH5gY2asD@zznH}I}(rZ@c5U6w61hM+8ICIA^X5Bb_y5S3+Ek9ZEl z?*ZiH6)kwCkWA9=3-~w+ybxpb72*#cb**=;xoOc-8{zY$u4h2jm&_e_|3vks1>z4m zyW|UdA7osj&Gdd{qvpWomslu=C3DC0a4C$PYho(mXt{8+7A!aLmV1?-F5{U-{R6-s z7S&pX40O4W@EV3)`(C+$$tUv>rxw@2uFws+DMVW2w%FV(WQJ|+Y;PayPf*F(1Z1bL z$ai!Nas@WuGhoMA{mgejl2}C17cwhFmN};U9X}-Ax=0m z8LFRzK%gdGF7UsHAV_p9TP(_dx;;gWjFo=yV32S5Rp}`9gRl$dVGx^z zIRXc$0x^PPQcT>eXj)8)GpVPfCg9^VoIGZAhEj-9ZoEyJZRhTcf@)xWC{G-a!0EG2 z12)=TwMbDLh|2~dWCzh$!B%A<=fbrZ* zr@HbND!)B8krMZ!}!{k#kU?KMWr%Vy+`OC5Gf&KSNCiUwIC%c)XSa0u9q}_JKQ8dS^75 z)G!H)#fmR3E^hlgJpTSR7mSzI2O$SEVrrJKK0(aqspClaSWcF!as!;nsIhY8ul$OP zW1tM_Od2P44g1R01MR9SkR&xf4$8VWEvk*IvZ0(%Ne{|*S`Gc`Ull1EfIF!Yd2T6# zD(QNYpu6NfG4!)DF6Pv==8pDvkHB4)u@(}Xi?q6^M@WWEAB2*L=Q8fsaUd)Wu6YlUA=6OI{n6=DYq>2wy0@M}xUR5g_98V|6+OJZw_rEp6_hdQTD(++ks-5|8R zt2T^x6LfYh@IoSx&ev_guc`v;`_XBSE#BGmxdxn@uVqy=`2$UE+YwDU4%T&t-UnA2->BWX@!{F}Q1?(g+ztZK+A)3BEVlToJ@%Jqb*CWB0fEP!ez)XWyU)&TMF^E?*(Vh~<4IkRe%Z|xYG_Tfj-($IL`QAJSia2G$f`nQ0(PFGj~KJ>!#B?iAiwL;<{rdz zTi!N`40S-Q2rhvNX@RdEkfkakMhfh0Z+~R8R;+=r}Y>8zH#E$z+oY-XZRCt(Px@JFd5@epIpS2f$rkchu>VJ7jAs$ za+ZqFAp$xS5TJ&Lc?r)HIJd?7hpofXyefrI!Ssg6_D#U8S(vljr~v`auI02>4u#lf zv5=K~n_5>v{xu56osqn2KDITkGL~)t7E#CeMMCJe!8^y1IVZF83gC*=us|I?CNw;N ziZx{681lQv&cU(drVxx)*JOyN_z}uGQHfCA--LCu}ILc<3 literal 20756 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 ZwO^{cll(l*?-OA2J+@Ayf}MW<_)ngU(9-|_ diff --git a/third_party/packages/flutter_svg/test/no_width_height_test.dart b/third_party/packages/flutter_svg/test/no_width_height_test.dart index 3efffbbb45b1..58bcf5f50fd2 100644 --- a/third_party/packages/flutter_svg/test/no_width_height_test.dart +++ b/third_party/packages/flutter_svg/test/no_width_height_test.dart @@ -27,19 +27,19 @@ class ColumnsAndRows extends StatelessWidget { @override Widget build(BuildContext context) { - return Column( + return const Column( children: [ - Row(children: const [ + Row(children: [ ImageWithText(), ]), Row( - children: const [ + children: [ ImageWithText(), ImageWithText(), ], ), Row( - children: const [ + children: [ ImageWithText(), ImageWithText(), ImageWithText(), @@ -47,7 +47,7 @@ class ColumnsAndRows extends StatelessWidget { ], ), Row( - children: const [ + children: [ ImageWithText(), ImageWithText(), ImageWithText(), @@ -57,7 +57,7 @@ class ColumnsAndRows extends StatelessWidget { ], ), Row( - children: const [ + children: [ ImageWithText(), ImageWithText(), ImageWithText(), diff --git a/third_party/packages/flutter_svg/test/widget_svg_test.dart b/third_party/packages/flutter_svg/test/widget_svg_test.dart index 99c270aa82e3..04f4ff821081 100644 --- a/third_party/packages/flutter_svg/test/widget_svg_test.dart +++ b/third_party/packages/flutter_svg/test/widget_svg_test.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; -import 'dart:ui' show window; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; @@ -43,6 +42,8 @@ void main() { late FakeHttpClientResponse fakeResponse; late FakeHttpClientRequest fakeRequest; late FakeHttpClient fakeHttpClient; + final MediaQueryData mediaQueryData = + MediaQueryData.fromView(PlatformDispatcher.instance.implicitView!); setUpAll(() { final LocalFileComparator oldComparator = @@ -107,7 +108,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: RepaintBoundary( key: key, child: SvgPicture.string( @@ -127,7 +128,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: Center( key: key, child: SvgPicture.string( @@ -145,7 +146,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: Center( key: key, child: SvgPicture.string( @@ -163,7 +164,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: RepaintBoundary( key: key, child: Directionality( @@ -204,7 +205,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: RepaintBoundary( key: key, child: Directionality( @@ -245,7 +246,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: RepaintBoundary( key: key, child: SvgPicture.memory( @@ -264,7 +265,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: RepaintBoundary( key: key, child: SvgPicture.asset( @@ -286,7 +287,7 @@ void main() { Directionality( textDirection: TextDirection.ltr, child: MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: DefaultAssetBundle( bundle: fakeAsset, child: RepaintBoundary( @@ -309,7 +310,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: RepaintBoundary( key: key, child: SvgPicture.network( @@ -328,7 +329,7 @@ void main() { final GlobalKey key = GlobalKey(); await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: RepaintBoundary( key: key, child: SvgPicture.network('test.svg', @@ -365,7 +366,7 @@ void main() { fakeResponse.statusCode = 400; await tester.pumpWidget( MediaQuery( - data: MediaQueryData.fromWindow(window), + data: mediaQueryData, child: SvgPicture.network( 'notFound.svg', ), From fa4df358ae7910f18aa01efdd877d6da44777c3c Mon Sep 17 00:00:00 2001 From: Dan Field Date: Thu, 18 May 2023 11:20:44 -0700 Subject: [PATCH 496/512] License file --- third_party/packages/flutter_svg/LICENSE | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 third_party/packages/flutter_svg/LICENSE diff --git a/third_party/packages/flutter_svg/LICENSE b/third_party/packages/flutter_svg/LICENSE new file mode 100644 index 000000000000..89a79eb0214e --- /dev/null +++ b/third_party/packages/flutter_svg/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018 Dan Field + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file From e0d175cc957bde8af3037aa9da89d563342745a6 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Fri, 26 May 2023 20:58:10 -0700 Subject: [PATCH 497/512] License for _test --- third_party/packages/flutter_svg_test/LICENSE | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 third_party/packages/flutter_svg_test/LICENSE diff --git a/third_party/packages/flutter_svg_test/LICENSE b/third_party/packages/flutter_svg_test/LICENSE new file mode 100644 index 000000000000..89a79eb0214e --- /dev/null +++ b/third_party/packages/flutter_svg_test/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2018 Dan Field + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file From 5e696837b73f35d2a7536f7cb0abea55d92b9560 Mon Sep 17 00:00:00 2001 From: tattuu Date: Sun, 28 May 2023 04:12:34 +0900 Subject: [PATCH 498/512] Fix typo in README.md (#929) --- third_party/packages/flutter_svg/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/packages/flutter_svg/README.md b/third_party/packages/flutter_svg/README.md index 64aa45bcdffb..15ba72081405 100644 --- a/third_party/packages/flutter_svg/README.md +++ b/third_party/packages/flutter_svg/README.md @@ -66,7 +66,7 @@ final PictureInfo pictureInfo = await vg.loadPicture(SvgStringLoader(rawSvg), nu // You can draw the picture to a canvas: canvas.drawPicture(pictureInfo.picture); -// Or convert the picture to a an image: +// Or convert the picture to an image: final ui.Image image = pictureInfo.picture.toImage(...); pictureInfo.picture.dispose(); From e4afb7b5331f70b49f1a3f8b025e6273b1aa5123 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Mon, 12 Jun 2023 10:29:59 -0700 Subject: [PATCH 499/512] Fix broken textDirection (#940) --- third_party/packages/flutter_svg/CHANGELOG.md | 4 ++++ third_party/packages/flutter_svg/lib/svg.dart | 1 + third_party/packages/flutter_svg/pubspec.yaml | 8 ++++---- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md index 91f21a0db508..393bce6a8bfc 100644 --- a/third_party/packages/flutter_svg/CHANGELOG.md +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 2.0.7 + +- Fix broken `matchTextDirection`. + ## 2.0.6 - Fix test-only issues with latest Flutter stable (3.10). diff --git a/third_party/packages/flutter_svg/lib/svg.dart b/third_party/packages/flutter_svg/lib/svg.dart index ae2d221d6e1e..e4fa81767c62 100644 --- a/third_party/packages/flutter_svg/lib/svg.dart +++ b/third_party/packages/flutter_svg/lib/svg.dart @@ -496,6 +496,7 @@ class SvgPicture extends StatelessWidget { colorFilter: colorFilter, placeholderBuilder: placeholderBuilder, clipViewbox: !allowDrawingOutsideViewBox, + matchTextDirection: matchTextDirection, ); } } diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml index 814e81676401..c6642e584590 100644 --- a/third_party/packages/flutter_svg/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -2,14 +2,14 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.6 +version: 2.0.7 dependencies: flutter: sdk: flutter - vector_graphics: ^1.1.6 - vector_graphics_codec: ^1.1.6 - vector_graphics_compiler: ^1.1.6 + vector_graphics: ^1.1.7 + vector_graphics_codec: ^1.1.7 + vector_graphics_compiler: ^1.1.7 dev_dependencies: flutter_test: From 6cf1dfbb50486e28ad677d097c5dc42c5340f2cd Mon Sep 17 00:00:00 2001 From: GP4cK Date: Fri, 14 Jul 2023 00:57:12 +0800 Subject: [PATCH 500/512] Adds DefaultSvgTheme (#964) --- third_party/packages/flutter_svg/CHANGELOG.md | 4 + .../flutter_svg/lib/src/default_theme.dart | 42 ++++ .../packages/flutter_svg/lib/src/loaders.dart | 30 ++- third_party/packages/flutter_svg/lib/svg.dart | 15 +- .../flutter_svg/test/default_theme_test.dart | 195 ++++++++++++++++++ 5 files changed, 272 insertions(+), 14 deletions(-) create mode 100644 third_party/packages/flutter_svg/lib/src/default_theme.dart create mode 100644 third_party/packages/flutter_svg/test/default_theme_test.dart diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md index 393bce6a8bfc..f92681232a64 100644 --- a/third_party/packages/flutter_svg/CHANGELOG.md +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 2.0.8 + +- Adds back `DefaultSvgTheme`. + ## 2.0.7 - Fix broken `matchTextDirection`. diff --git a/third_party/packages/flutter_svg/lib/src/default_theme.dart b/third_party/packages/flutter_svg/lib/src/default_theme.dart new file mode 100644 index 000000000000..a44a981d6669 --- /dev/null +++ b/third_party/packages/flutter_svg/lib/src/default_theme.dart @@ -0,0 +1,42 @@ +import 'package:flutter/widgets.dart'; + +import 'loaders.dart'; + +/// The SVG theme to apply to descendant [SvgPicture] widgets +/// which don't have explicit theme values. +class DefaultSvgTheme extends InheritedTheme { + /// Creates a default SVG theme for the given subtree + /// using the provided [theme]. + const DefaultSvgTheme({ + Key? key, + required Widget child, + required this.theme, + }) : super(key: key, child: child); + + /// The SVG theme to apply. + final SvgTheme theme; + + /// The closest instance of this class that encloses the given context. + /// + /// Typical usage is as follows: + /// + /// ```dart + /// DefaultSvgTheme theme = DefaultSvgTheme.of(context); + /// ``` + static DefaultSvgTheme? of(BuildContext context) { + return context.dependOnInheritedWidgetOfExactType(); + } + + @override + bool updateShouldNotify(DefaultSvgTheme oldWidget) { + return theme != oldWidget.theme; + } + + @override + Widget wrap(BuildContext context, Widget child) { + return DefaultSvgTheme( + theme: theme, + child: child, + ); + } +} diff --git a/third_party/packages/flutter_svg/lib/src/loaders.dart b/third_party/packages/flutter_svg/lib/src/loaders.dart index 5ebd8dd66641..9ec1fde325e7 100644 --- a/third_party/packages/flutter_svg/lib/src/loaders.dart +++ b/third_party/packages/flutter_svg/lib/src/loaders.dart @@ -3,13 +3,14 @@ import 'dart:convert' show utf8; import 'package:flutter/foundation.dart' hide compute; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; -import 'package:flutter_svg/src/utilities/http.dart'; import 'package:vector_graphics/vector_graphics.dart'; import 'package:vector_graphics_compiler/vector_graphics_compiler.dart' as vg; import '../svg.dart' show svg; +import 'default_theme.dart'; import 'utilities/compute.dart'; import 'utilities/file.dart'; +import 'utilities/http.dart'; /// A theme used when decoding an SVG picture. @immutable @@ -111,12 +112,12 @@ class _DelegateVgColorMapper extends vg.ColorMapper { abstract class SvgLoader extends BytesLoader { /// See class doc. const SvgLoader({ - this.theme = const SvgTheme(), + this.theme, this.colorMapper, }); /// The theme to determine currentColor and font sizing attributes. - final SvgTheme theme; + final SvgTheme? theme; /// The [ColorMapper] used to transform colors from the SVG, if any. final ColorMapper? colorMapper; @@ -130,7 +131,24 @@ abstract class SvgLoader extends BytesLoader { Future prepareMessage(BuildContext? context) => SynchronousFuture(null); + /// Returns the svg theme. + @visibleForTesting + @protected + SvgTheme getTheme(BuildContext? context) { + if (theme != null) { + return theme!; + } + if (context != null) { + final SvgTheme? defaultTheme = DefaultSvgTheme.of(context)?.theme; + if (defaultTheme != null) { + return defaultTheme; + } + } + return const SvgTheme(); + } + Future _load(BuildContext? context) { + final SvgTheme theme = getTheme(context); return prepareMessage(context).then((T? message) { return compute((T? message) { return vg @@ -160,6 +178,7 @@ abstract class SvgLoader extends BytesLoader { @override SvgCacheKey cacheKey(BuildContext? context) { + final SvgTheme theme = getTheme(context); return SvgCacheKey(keyData: this, theme: theme, colorMapper: colorMapper); } } @@ -172,13 +191,13 @@ abstract class SvgLoader extends BytesLoader { class SvgCacheKey { /// See [SvgCacheKey]. const SvgCacheKey({ - required this.theme, required this.keyData, required this.colorMapper, + this.theme, }); /// The theme for this cached SVG. - final SvgTheme theme; + final SvgTheme? theme; /// The other key data for the SVG. /// @@ -365,6 +384,7 @@ class SvgAssetLoader extends SvgLoader { @override SvgCacheKey cacheKey(BuildContext? context) { + final SvgTheme theme = getTheme(context); return SvgCacheKey( theme: theme, colorMapper: colorMapper, diff --git a/third_party/packages/flutter_svg/lib/svg.dart b/third_party/packages/flutter_svg/lib/svg.dart index e4fa81767c62..ca42137425e2 100644 --- a/third_party/packages/flutter_svg/lib/svg.dart +++ b/third_party/packages/flutter_svg/lib/svg.dart @@ -12,6 +12,7 @@ export 'package:vector_graphics/vector_graphics.dart' show BytesLoader, vg, VectorGraphicUtilities, PictureInfo; export 'src/cache.dart'; +export 'src/default_theme.dart'; export 'src/loaders.dart'; /// Instance for [Svg]'s utility methods, which can produce a [DrawableRoot] @@ -84,7 +85,6 @@ class SvgPicture extends StatelessWidget { this.semanticsLabel, this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, - this.theme = const SvgTheme(), @deprecated bool cacheColorFilter = false, }) : super(key: key); @@ -179,7 +179,7 @@ class SvgPicture extends StatelessWidget { this.semanticsLabel, this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, - this.theme = const SvgTheme(), + SvgTheme? theme, ui.ColorFilter? colorFilter, @deprecated ui.Color? color, @deprecated ui.BlendMode colorBlendMode = ui.BlendMode.srcIn, @@ -243,7 +243,7 @@ class SvgPicture extends StatelessWidget { this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, @deprecated bool cacheColorFilter = false, - this.theme = const SvgTheme(), + SvgTheme? theme, }) : bytesLoader = SvgNetworkLoader(url, headers: headers, theme: theme), colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode), super(key: key); @@ -294,7 +294,7 @@ class SvgPicture extends StatelessWidget { this.semanticsLabel, this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, - this.theme = const SvgTheme(), + SvgTheme? theme, @deprecated bool cacheColorFilter = false, }) : bytesLoader = SvgFileLoader(file, theme: theme), colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode), @@ -343,7 +343,7 @@ class SvgPicture extends StatelessWidget { this.semanticsLabel, this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, - this.theme = const SvgTheme(), + SvgTheme? theme, @deprecated bool cacheColorFilter = false, }) : bytesLoader = SvgBytesLoader(bytes, theme: theme), colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode), @@ -392,7 +392,7 @@ class SvgPicture extends StatelessWidget { this.semanticsLabel, this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, - this.theme = const SvgTheme(), + SvgTheme? theme, @deprecated bool cacheColorFilter = false, }) : bytesLoader = SvgStringLoader(string, theme: theme), colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode), @@ -479,9 +479,6 @@ class SvgPicture extends StatelessWidget { /// The color filter, if any, to apply to this widget. final ColorFilter? colorFilter; - /// The theme used when parsing SVG elements. - final SvgTheme theme; - @override Widget build(BuildContext context) { return createCompatVectorGraphic( diff --git a/third_party/packages/flutter_svg/test/default_theme_test.dart b/third_party/packages/flutter_svg/test/default_theme_test.dart new file mode 100644 index 000000000000..1078ae498036 --- /dev/null +++ b/third_party/packages/flutter_svg/test/default_theme_test.dart @@ -0,0 +1,195 @@ +import 'package:flutter/widgets.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:flutter_test/flutter_test.dart'; + +void main() { + group('DefaultSvgTheme', () { + testWidgets('changes propagate to SvgPicture', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + currentColor: Color(0xFF733821), + fontSize: 14.0, + xHeight: 6.0, + ); + + final SvgPicture svgPictureWidget = SvgPicture.string(''' + + +'''); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + + SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + BuildContext context = tester.element(find.byType(SvgPicture)); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context), + equals(svgTheme), + ); + + const SvgTheme anotherSvgTheme = SvgTheme( + currentColor: Color(0xFF05290E), + fontSize: 12.0, + xHeight: 7.0, + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: anotherSvgTheme, + child: svgPictureWidget, + )); + context = tester.element(find.byType(SvgPicture)); + + svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context), + equals(anotherSvgTheme), + ); + }); + + testWidgets( + 'currentColor from the widget\'s theme takes precedence over ' + 'the theme from DefaultSvgTheme', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + currentColor: Color(0xFF733821), + fontSize: 14.0, + ); + + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + theme: const SvgTheme( + currentColor: Color(0xFF05290E), + fontSize: 14.0, + ), + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + final BuildContext context = tester.element(find.byType(SvgPicture)); + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader) + .getTheme(context) + .currentColor, + equals(const Color(0xFF05290E)), + ); + }); + + testWidgets( + 'fontSize from the widget\'s theme takes precedence over ' + 'the theme from DefaultSvgTheme', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + fontSize: 14.0, + ); + + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + theme: const SvgTheme( + fontSize: 12.0, + ), + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + final BuildContext context = tester.element(find.byType(SvgPicture)); + + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context).fontSize, + equals(12.0), + ); + }); + + testWidgets( + 'fontSize defaults to 14 ' + 'if no widget\'s theme, DefaultSvgTheme or DefaultTextStyle is provided', + (WidgetTester tester) async { + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + ); + + await tester.pumpWidget(svgPictureWidget); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + final BuildContext context = tester.element(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context).fontSize, + equals(14.0), + ); + }); + + testWidgets( + 'xHeight from the widget\'s theme takes precedence over ' + 'the theme from DefaultSvgTheme', (WidgetTester tester) async { + const SvgTheme svgTheme = SvgTheme( + fontSize: 14.0, + xHeight: 6.5, + ); + + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + theme: const SvgTheme( + fontSize: 12.0, + xHeight: 7.0, + ), + ); + + await tester.pumpWidget(DefaultSvgTheme( + theme: svgTheme, + child: svgPictureWidget, + )); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + final BuildContext context = tester.element(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context).xHeight, + equals(7.0), + ); + }); + + testWidgets( + 'xHeight defaults to the font size divided by 2 (7.0) ' + 'if no widget\'s theme or DefaultSvgTheme is provided', + (WidgetTester tester) async { + final SvgPicture svgPictureWidget = SvgPicture.string( + ''' + + +''', + ); + + await tester.pumpWidget(svgPictureWidget); + + final SvgPicture svgPicture = tester.firstWidget(find.byType(SvgPicture)); + final BuildContext context = tester.element(find.byType(SvgPicture)); + expect(svgPicture, isNotNull); + expect( + (svgPicture.bytesLoader as SvgStringLoader).getTheme(context).xHeight, + equals(7.0), + ); + }); + }); +} From 9869ae19d3ea9e20628ced04b435ba40d6d8df6f Mon Sep 17 00:00:00 2001 From: Andrew Brampton Date: Mon, 16 Oct 2023 09:58:13 -0700 Subject: [PATCH 501/512] Added debugFillProperties to SvgPicture to enable easier debugging. (#999) --- third_party/packages/flutter_svg/lib/svg.dart | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/third_party/packages/flutter_svg/lib/svg.dart b/third_party/packages/flutter_svg/lib/svg.dart index ca42137425e2..3ac7c6a75796 100644 --- a/third_party/packages/flutter_svg/lib/svg.dart +++ b/third_party/packages/flutter_svg/lib/svg.dart @@ -496,4 +496,22 @@ class SvgPicture extends StatelessWidget { matchTextDirection: matchTextDirection, ); } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + + properties.add(StringProperty('bytesLoader', bytesLoader.toString(), showName: false)); + properties.add(DoubleProperty('width', width, defaultValue: null)); + properties.add(DoubleProperty('height', height, defaultValue: null)); + properties.add(EnumProperty('alignment', alignment, defaultValue: Alignment.center)); + properties.add(DiagnosticsProperty('allowDrawingOutsideViewBox', allowDrawingOutsideViewBox, defaultValue: false)); + properties.add(EnumProperty('clipBehavior', clipBehavior, defaultValue: BoxFit.contain)); + properties.add(StringProperty('colorFilter', colorFilter.toString(), defaultValue: null)); + properties.add(EnumProperty('fit', fit, defaultValue: BoxFit.contain)); + properties.add(DiagnosticsProperty('placeholderBuilder', placeholderBuilder, defaultValue: null)); + properties.add(DiagnosticsProperty('matchTextDirection', matchTextDirection, defaultValue: false)); + properties.add(DiagnosticsProperty('excludeFromSemantics', excludeFromSemantics, defaultValue: false)); + properties.add(StringProperty('semanticsLabel', semanticsLabel, defaultValue: null)); + } } From 00c6ee5d4642fac59df4f043e0de4021c4bf87eb Mon Sep 17 00:00:00 2001 From: Andrew Brampton Date: Tue, 17 Oct 2023 13:42:08 -0700 Subject: [PATCH 502/512] Fixed formatting broken in https://github.com/dnfield/flutter_svg/pull/999 (#1001) I originally didn't format the debugFillProperties because that seems to be what happens in the main flutter library (presumably for better readability), but here it breaks the presubmits. So here is a quick `dart format`. --- third_party/packages/flutter_svg/lib/svg.dart | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/third_party/packages/flutter_svg/lib/svg.dart b/third_party/packages/flutter_svg/lib/svg.dart index 3ac7c6a75796..a87d5180c72d 100644 --- a/third_party/packages/flutter_svg/lib/svg.dart +++ b/third_party/packages/flutter_svg/lib/svg.dart @@ -501,17 +501,31 @@ class SvgPicture extends StatelessWidget { void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); - properties.add(StringProperty('bytesLoader', bytesLoader.toString(), showName: false)); + properties.add( + StringProperty('bytesLoader', bytesLoader.toString(), showName: false)); properties.add(DoubleProperty('width', width, defaultValue: null)); properties.add(DoubleProperty('height', height, defaultValue: null)); - properties.add(EnumProperty('alignment', alignment, defaultValue: Alignment.center)); - properties.add(DiagnosticsProperty('allowDrawingOutsideViewBox', allowDrawingOutsideViewBox, defaultValue: false)); - properties.add(EnumProperty('clipBehavior', clipBehavior, defaultValue: BoxFit.contain)); - properties.add(StringProperty('colorFilter', colorFilter.toString(), defaultValue: null)); - properties.add(EnumProperty('fit', fit, defaultValue: BoxFit.contain)); - properties.add(DiagnosticsProperty('placeholderBuilder', placeholderBuilder, defaultValue: null)); - properties.add(DiagnosticsProperty('matchTextDirection', matchTextDirection, defaultValue: false)); - properties.add(DiagnosticsProperty('excludeFromSemantics', excludeFromSemantics, defaultValue: false)); - properties.add(StringProperty('semanticsLabel', semanticsLabel, defaultValue: null)); + properties.add(EnumProperty('alignment', alignment, + defaultValue: Alignment.center)); + properties.add(DiagnosticsProperty( + 'allowDrawingOutsideViewBox', allowDrawingOutsideViewBox, + defaultValue: false)); + properties.add(EnumProperty('clipBehavior', clipBehavior, + defaultValue: BoxFit.contain)); + properties.add(StringProperty('colorFilter', colorFilter.toString(), + defaultValue: null)); + properties + .add(EnumProperty('fit', fit, defaultValue: BoxFit.contain)); + properties.add(DiagnosticsProperty( + 'placeholderBuilder', placeholderBuilder, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'matchTextDirection', matchTextDirection, + defaultValue: false)); + properties.add(DiagnosticsProperty( + 'excludeFromSemantics', excludeFromSemantics, + defaultValue: false)); + properties.add( + StringProperty('semanticsLabel', semanticsLabel, defaultValue: null)); } } From 30dcccf20582a674dd728a6aafb3e570e06905f3 Mon Sep 17 00:00:00 2001 From: Andrew Brampton Date: Tue, 17 Oct 2023 14:38:28 -0700 Subject: [PATCH 503/512] Fixes issue where a incorrect key was being given to the ImageCache (#1000) * Fixed the hashcode in SvgStringLoader and SvgBytesLoader. It was accidently using the svg global object, instead of a local field. This caused caches (such as PaintingBinding.instance.imageCache) to misbehave. * Add a test which ensures the embedded image in a SvgPicture is not incorrectly cached and carried over. --- .../packages/flutter_svg/lib/src/loaders.dart | 4 +- .../test/golden_widget/image_blue.png | Bin 0 -> 3276 bytes .../test/golden_widget/image_red.png | Bin 0 -> 3278 bytes .../flutter_svg/test/widget_svg_test.dart | 48 ++++++++++++++++++ 4 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 third_party/packages/flutter_svg/test/golden_widget/image_blue.png create mode 100644 third_party/packages/flutter_svg/test/golden_widget/image_red.png diff --git a/third_party/packages/flutter_svg/lib/src/loaders.dart b/third_party/packages/flutter_svg/lib/src/loaders.dart index 9ec1fde325e7..0c9931d062ed 100644 --- a/third_party/packages/flutter_svg/lib/src/loaders.dart +++ b/third_party/packages/flutter_svg/lib/src/loaders.dart @@ -237,7 +237,7 @@ class SvgStringLoader extends SvgLoader { } @override - int get hashCode => Object.hash(svg, theme, colorMapper); + int get hashCode => Object.hash(_svg, theme, colorMapper); @override bool operator ==(Object other) { @@ -266,7 +266,7 @@ class SvgBytesLoader extends SvgLoader { String provideSvg(void message) => utf8.decode(bytes, allowMalformed: true); @override - int get hashCode => Object.hash(svg, theme, colorMapper); + int get hashCode => Object.hash(bytes, theme, colorMapper); @override bool operator ==(Object other) { diff --git a/third_party/packages/flutter_svg/test/golden_widget/image_blue.png b/third_party/packages/flutter_svg/test/golden_widget/image_blue.png new file mode 100644 index 0000000000000000000000000000000000000000..1561f73cf184f8627c1ef907041bfc5d802c20c9 GIT binary patch literal 3276 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI zLpXq-h9jkefq|#Y)5S5QV$R#^2L&AhL=HH_KX!X6Q#v92##)8zYkH^e?0di1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI zLpXq-h9jkefq|#O)5S5QV$R#^2L&AhL=GHqf9&>DrgTF7jkOBba}KYLF+To^jiEvR zX4<){yf)viGBPk6sFx66U{FYQU|?wIVFU^ov9T~PoEQ}x4Uo~qFq#oYONP->akNGl rtqn(O!_nGsv^E^A4YAjTXLz;$vu#*uYk3>kCt>h(^>bP0l+XkK5kl)* literal 0 HcmV?d00001 diff --git a/third_party/packages/flutter_svg/test/widget_svg_test.dart b/third_party/packages/flutter_svg/test/widget_svg_test.dart index 04f4ff821081..f464e01b0019 100644 --- a/third_party/packages/flutter_svg/test/widget_svg_test.dart +++ b/third_party/packages/flutter_svg/test/widget_svg_test.dart @@ -728,6 +728,54 @@ void main() { matchesGoldenFile('golden_widget/two_of_same.png'), ); }); + + // This tests https://github.com/dnfield/flutter_svg/issues/990 + // Where embedded images were being incorrectly cached. + testWidgets('SvgPicture - with cached images', (WidgetTester tester) async { + // Simple red and blue 10x10 squares. + // Borrowed from https://gist.github.com/ondrek/7413434?permalink_comment_id=4674255#gistcomment-4674255 + final Map images = { + 'red': + 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mP8z8BQz0AEYBxVSF+FABJADveWkH6oAAAAAElFTkSuQmCC', + 'blue': + 'iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAFUlEQVR42mNkYPhfz0AEYBxVSF+FAP5FDvcfRYWgAAAAAElFTkSuQmCC', + }; + + // We keep pumping widgets into the same tester, to ensure the same cache + // is used on each iteration. + for (final String key in images.keys) { + final String image = images[key]!; + final String svgStr = ''' + + '''; + + // First try with SvgPicture.string + await tester.pumpWidget(RepaintBoundary( + child: SvgPicture.string(svgStr), + )); + await tester.runAsync(() => vg.waitForPendingDecodes()); + await tester.pumpAndSettle(); + + Finder widgetFinder = find.byType(SvgPicture); + expect(widgetFinder, findsOneWidget); + await expectLater( + widgetFinder, matchesGoldenFile('golden_widget/image_$key.png')); + + // Then with SvgPicture.memory + await tester.pumpWidget(RepaintBoundary( + child: SvgPicture.memory(utf8.encode(svgStr) as Uint8List), + )); + await tester.runAsync(() => vg.waitForPendingDecodes()); + await tester.pumpAndSettle(); + + widgetFinder = find.byType(SvgPicture); + expect(widgetFinder, findsOneWidget); + await expectLater( + widgetFinder, matchesGoldenFile('golden_widget/image_$key.png')); + } + }); } class FakeAssetBundle extends Fake implements AssetBundle { From e82a974492f4ef37fc3091314c6bcba9ede4c4fa Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 24 Oct 2023 16:04:47 -0700 Subject: [PATCH 504/512] fixes --- third_party/packages/flutter_svg/CHANGELOG.md | 3 +++ third_party/packages/flutter_svg/example/pubspec.yaml | 6 +++--- third_party/packages/flutter_svg/lib/svg.dart | 2 +- third_party/packages/flutter_svg/pubspec.yaml | 6 +++--- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md index f92681232a64..d7781e7688ff 100644 --- a/third_party/packages/flutter_svg/CHANGELOG.md +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -3,6 +3,9 @@ ## 2.0.8 - Adds back `DefaultSvgTheme`. +- Bump vector_graphics to 1.1.9+1 +- Adds debugFillProperties +- Fix bug for cache keys. ## 2.0.7 diff --git a/third_party/packages/flutter_svg/example/pubspec.yaml b/third_party/packages/flutter_svg/example/pubspec.yaml index a4f3c406da1a..c6691b6cf1a2 100644 --- a/third_party/packages/flutter_svg/example/pubspec.yaml +++ b/third_party/packages/flutter_svg/example/pubspec.yaml @@ -32,8 +32,8 @@ environment: # dependency_overrides: # vector_graphics_codec: -# path: ../../vector_graphics/packages/vector_graphics_codec +# path: ../../../../vector_graphics/packages/vector_graphics_codec # vector_graphics_compiler: -# path: ../../vector_graphics/packages/vector_graphics_compiler +# path: ../../../../vector_graphics/packages/vector_graphics_compiler # vector_graphics: -# path: ../../vector_graphics/packages/vector_graphics +# path: ../../../../vector_graphics/packages/vector_graphics diff --git a/third_party/packages/flutter_svg/lib/svg.dart b/third_party/packages/flutter_svg/lib/svg.dart index a87d5180c72d..bfad274fd4ac 100644 --- a/third_party/packages/flutter_svg/lib/svg.dart +++ b/third_party/packages/flutter_svg/lib/svg.dart @@ -505,7 +505,7 @@ class SvgPicture extends StatelessWidget { StringProperty('bytesLoader', bytesLoader.toString(), showName: false)); properties.add(DoubleProperty('width', width, defaultValue: null)); properties.add(DoubleProperty('height', height, defaultValue: null)); - properties.add(EnumProperty('alignment', alignment, + properties.add(DiagnosticsProperty('alignment', alignment, defaultValue: Alignment.center)); properties.add(DiagnosticsProperty( 'allowDrawingOutsideViewBox', allowDrawingOutsideViewBox, diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml index c6642e584590..fcbb67ff7435 100644 --- a/third_party/packages/flutter_svg/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -7,9 +7,9 @@ version: 2.0.7 dependencies: flutter: sdk: flutter - vector_graphics: ^1.1.7 - vector_graphics_codec: ^1.1.7 - vector_graphics_compiler: ^1.1.7 + vector_graphics: ^1.1.9+1 + vector_graphics_codec: ^1.1.9+1 + vector_graphics_compiler: ^1.1.9+1 dev_dependencies: flutter_test: From 2663a4324f380aad0d1da8feffbbcb635710bb12 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 24 Oct 2023 16:06:04 -0700 Subject: [PATCH 505/512] missing file --- third_party/packages/flutter_svg/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml index fcbb67ff7435..689fdee5fac8 100644 --- a/third_party/packages/flutter_svg/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.7 +version: 2.0.8 dependencies: flutter: From 9dc43db4ec3f056f0b40a873d09738b4c034467c Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 31 Oct 2023 15:10:12 -0700 Subject: [PATCH 506/512] Fix semver violation for SvgPicture (#1008) * Fix semver violation for SvgPicture * fix for older versions of flutter? --- third_party/packages/flutter_svg/CHANGELOG.md | 6 ++ third_party/packages/flutter_svg/lib/svg.dart | 81 +++++++++++++------ third_party/packages/flutter_svg/pubspec.yaml | 2 +- .../flutter_svg/test/widget_svg_test.dart | 3 +- 4 files changed, 65 insertions(+), 27 deletions(-) diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md index d7781e7688ff..4fce866900c6 100644 --- a/third_party/packages/flutter_svg/CHANGELOG.md +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -1,5 +1,11 @@ # CHANGES +## 2.0.9 + +- Adds back `SvgPicture(theme:)` parameter with a deprecation. Although this + parameter was inherently broken, removing it would require a major semver + bump, which would cause consumers to miss out on important fixes. + ## 2.0.8 - Adds back `DefaultSvgTheme`. diff --git a/third_party/packages/flutter_svg/lib/svg.dart b/third_party/packages/flutter_svg/lib/svg.dart index bfad274fd4ac..785cfa146946 100644 --- a/third_party/packages/flutter_svg/lib/svg.dart +++ b/third_party/packages/flutter_svg/lib/svg.dart @@ -85,6 +85,10 @@ class SvgPicture extends StatelessWidget { this.semanticsLabel, this.excludeFromSemantics = false, this.clipBehavior = Clip.hardEdge, + @Deprecated( + 'No code should use this parameter. It never was implemented properly. ' + 'The SVG theme must be set on the bytesLoader.') + SvgTheme? theme, @deprecated bool cacheColorFilter = false, }) : super(key: key); @@ -501,31 +505,58 @@ class SvgPicture extends StatelessWidget { void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); - properties.add( - StringProperty('bytesLoader', bytesLoader.toString(), showName: false)); - properties.add(DoubleProperty('width', width, defaultValue: null)); - properties.add(DoubleProperty('height', height, defaultValue: null)); - properties.add(DiagnosticsProperty('alignment', alignment, - defaultValue: Alignment.center)); - properties.add(DiagnosticsProperty( - 'allowDrawingOutsideViewBox', allowDrawingOutsideViewBox, - defaultValue: false)); - properties.add(EnumProperty('clipBehavior', clipBehavior, - defaultValue: BoxFit.contain)); - properties.add(StringProperty('colorFilter', colorFilter.toString(), - defaultValue: null)); properties - .add(EnumProperty('fit', fit, defaultValue: BoxFit.contain)); - properties.add(DiagnosticsProperty( - 'placeholderBuilder', placeholderBuilder, - defaultValue: null)); - properties.add(DiagnosticsProperty( - 'matchTextDirection', matchTextDirection, - defaultValue: false)); - properties.add(DiagnosticsProperty( - 'excludeFromSemantics', excludeFromSemantics, - defaultValue: false)); - properties.add( - StringProperty('semanticsLabel', semanticsLabel, defaultValue: null)); + ..add(StringProperty( + 'bytesLoader', + bytesLoader.toString(), + showName: false, + )) + ..add(DoubleProperty('width', width, defaultValue: null)) + ..add(DoubleProperty('height', height, defaultValue: null)) + ..add(DiagnosticsProperty( + 'alignment', + alignment, + defaultValue: Alignment.center, + )) + ..add(DiagnosticsProperty( + 'allowDrawingOutsideViewBox', + allowDrawingOutsideViewBox, + defaultValue: false, + )) + ..add(EnumProperty( + 'clipBehavior', + clipBehavior, + defaultValue: BoxFit.contain, + )) + ..add(StringProperty( + 'colorFilter', + colorFilter.toString(), + defaultValue: null, + )) + ..add(EnumProperty( + 'fit', + fit, + defaultValue: BoxFit.contain, + )) + ..add(DiagnosticsProperty( + 'placeholderBuilder', + placeholderBuilder, + defaultValue: null, + )) + ..add(DiagnosticsProperty( + 'matchTextDirection', + matchTextDirection, + defaultValue: false, + )) + ..add(DiagnosticsProperty( + 'excludeFromSemantics', + excludeFromSemantics, + defaultValue: false, + )) + ..add(StringProperty( + 'semanticsLabel', + semanticsLabel, + defaultValue: null, + )); } } diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml index 689fdee5fac8..a5d77b936a89 100644 --- a/third_party/packages/flutter_svg/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -2,7 +2,7 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.8 +version: 2.0.9 dependencies: flutter: diff --git a/third_party/packages/flutter_svg/test/widget_svg_test.dart b/third_party/packages/flutter_svg/test/widget_svg_test.dart index f464e01b0019..8913907b882f 100644 --- a/third_party/packages/flutter_svg/test/widget_svg_test.dart +++ b/third_party/packages/flutter_svg/test/widget_svg_test.dart @@ -765,6 +765,7 @@ void main() { // Then with SvgPicture.memory await tester.pumpWidget(RepaintBoundary( + // ignore: unnecessary_cast child: SvgPicture.memory(utf8.encode(svgStr) as Uint8List), )); await tester.runAsync(() => vg.waitForPendingDecodes()); @@ -902,4 +903,4 @@ const String stickFigureSvgStr = ''' '''; -final Uint8List svgBytes = utf8.encode(svgStr) as Uint8List; +final Uint8List svgBytes = Uint8List.fromList(utf8.encode(svgStr)); From 77fabaac88890b292009a44389c1bdba97c54b1f Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 5 Dec 2023 13:39:07 -0800 Subject: [PATCH 507/512] skip out of date test --- third_party/packages/flutter_svg/test/no_width_height_test.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/third_party/packages/flutter_svg/test/no_width_height_test.dart b/third_party/packages/flutter_svg/test/no_width_height_test.dart index 58bcf5f50fd2..5c0955eb870f 100644 --- a/third_party/packages/flutter_svg/test/no_width_height_test.dart +++ b/third_party/packages/flutter_svg/test/no_width_height_test.dart @@ -18,6 +18,7 @@ void main() { await expectLater( find.byType(RepaintBoundary), matchesGoldenFile('golden_widget/columns_and_rows.png'), + skip: 'This golden needs updating', ); }, skip: !isLinux); } From 8fdc7acd853e4492cf7397b36cb14e1cf0a942b2 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 5 Dec 2023 13:44:13 -0800 Subject: [PATCH 508/512] ignore unnecessary cast --- .../packages/flutter_svg_test/test/flutter_svg_test_test.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart b/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart index a3a88e05f954..474b5e79fdb3 100644 --- a/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart +++ b/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart @@ -174,10 +174,12 @@ class _FakeHttpClientResponse extends Fake implements HttpClientResponse { } } +// Ignore this because the minimum flutter sdk needs this cast. +// ignore: unnecessary_cast final Uint8List _svgBytes = utf8.encode(_svgStr) as Uint8List; const String _svgStr = ''' - + '''; From ab9bf4fcf89228004de50f069e007b438ab77b64 Mon Sep 17 00:00:00 2001 From: Sam Rawlins Date: Tue, 5 Dec 2023 13:49:41 -0800 Subject: [PATCH 509/512] Avoid expanding the parameter type of operator== (#1017) Object.operator== takes an `Object`, and no Dart runtime passes a `null` value to an `==` implementation. SvgTheme's implementation should not have an expanded parameter type of `dynamic`. See https://github.com/flutter/flutter/issues/117838 for the overarching issue for Flutter. Co-authored-by: Dan Field --- third_party/packages/flutter_svg/lib/src/loaders.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/packages/flutter_svg/lib/src/loaders.dart b/third_party/packages/flutter_svg/lib/src/loaders.dart index 0c9931d062ed..ac781ef5faff 100644 --- a/third_party/packages/flutter_svg/lib/src/loaders.dart +++ b/third_party/packages/flutter_svg/lib/src/loaders.dart @@ -54,7 +54,7 @@ class SvgTheme { } @override - bool operator ==(dynamic other) { + bool operator ==(Object other) { if (other.runtimeType != runtimeType) { return false; } From 821cd418f317825d8331a958fd99e0fdbddeb5e6 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 20 Feb 2024 08:54:04 -0800 Subject: [PATCH 510/512] Use package:http, drop dart:html (#1038) * Use package:http, drop dart:html * Format --- third_party/packages/flutter_svg/CHANGELOG.md | 5 + .../packages/flutter_svg/lib/src/loaders.dart | 13 +- .../lib/src/utilities/_http_io.dart | 22 --- .../lib/src/utilities/_http_web.dart | 12 -- .../flutter_svg/lib/src/utilities/http.dart | 1 - third_party/packages/flutter_svg/lib/svg.dart | 9 +- third_party/packages/flutter_svg/pubspec.yaml | 9 +- .../flutter_svg/test/widget_svg_test.dart | 154 ++++++------------ 8 files changed, 76 insertions(+), 149 deletions(-) delete mode 100644 third_party/packages/flutter_svg/lib/src/utilities/_http_io.dart delete mode 100644 third_party/packages/flutter_svg/lib/src/utilities/_http_web.dart delete mode 100644 third_party/packages/flutter_svg/lib/src/utilities/http.dart diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md index 4fce866900c6..ea9a4e24198f 100644 --- a/third_party/packages/flutter_svg/CHANGELOG.md +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -1,5 +1,10 @@ # CHANGES +## 2.0.10 + +- Use package:http for network requests, and allow injection of the client. +- Bump vector_graphics dependency. + ## 2.0.9 - Adds back `SvgPicture(theme:)` parameter with a deprecation. Although this diff --git a/third_party/packages/flutter_svg/lib/src/loaders.dart b/third_party/packages/flutter_svg/lib/src/loaders.dart index ac781ef5faff..2996cc11f64f 100644 --- a/third_party/packages/flutter_svg/lib/src/loaders.dart +++ b/third_party/packages/flutter_svg/lib/src/loaders.dart @@ -3,6 +3,7 @@ import 'dart:convert' show utf8; import 'package:flutter/foundation.dart' hide compute; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; import 'package:vector_graphics/vector_graphics.dart'; import 'package:vector_graphics_compiler/vector_graphics_compiler.dart' as vg; @@ -10,7 +11,6 @@ import '../svg.dart' show svg; import 'default_theme.dart'; import 'utilities/compute.dart'; import 'utilities/file.dart'; -import 'utilities/http.dart'; /// A theme used when decoding an SVG picture. @immutable @@ -109,6 +109,7 @@ class _DelegateVgColorMapper extends vg.ColorMapper { /// A [BytesLoader] that parses a SVG data in an isolate and creates a /// vector_graphics binary representation. +@immutable abstract class SvgLoader extends BytesLoader { /// See class doc. const SvgLoader({ @@ -423,7 +424,8 @@ class SvgNetworkLoader extends SvgLoader { this.headers, super.theme, super.colorMapper, - }); + http.Client? httpClient, + }) : _httpClient = httpClient; /// The [Uri] encoded resource address. final String url; @@ -431,9 +433,12 @@ class SvgNetworkLoader extends SvgLoader { /// Optional HTTP headers to send as part of the request. final Map? headers; + final http.Client? _httpClient; + @override - Future prepareMessage(BuildContext? context) { - return httpGet(url, headers: headers); + Future prepareMessage(BuildContext? context) async { + final http.Client client = _httpClient ?? http.Client(); + return (await client.get(Uri.parse(url), headers: headers)).bodyBytes; } @override diff --git a/third_party/packages/flutter_svg/lib/src/utilities/_http_io.dart b/third_party/packages/flutter_svg/lib/src/utilities/_http_io.dart deleted file mode 100644 index 458a20725ad2..000000000000 --- a/third_party/packages/flutter_svg/lib/src/utilities/_http_io.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'dart:io'; -import 'dart:typed_data'; // ignore: unnecessary_import - -import 'package:flutter/foundation.dart'; - -/// Fetches an HTTP resource from the specified [url] using the specified [headers]. -Future httpGet(String url, {Map? headers}) async { - final HttpClient httpClient = HttpClient(); - final Uri uri = Uri.base.resolve(url); - final HttpClientRequest request = await httpClient.getUrl(uri); - if (headers != null) { - headers.forEach((String key, String value) { - request.headers.add(key, value); - }); - } - final HttpClientResponse response = await request.close(); - - if (response.statusCode != HttpStatus.ok) { - throw HttpException('Could not get network asset', uri: uri); - } - return consolidateHttpClientResponseBytes(response); -} diff --git a/third_party/packages/flutter_svg/lib/src/utilities/_http_web.dart b/third_party/packages/flutter_svg/lib/src/utilities/_http_web.dart deleted file mode 100644 index fc8b2c17e3f5..000000000000 --- a/third_party/packages/flutter_svg/lib/src/utilities/_http_web.dart +++ /dev/null @@ -1,12 +0,0 @@ -import 'dart:convert'; -import 'dart:html'; -import 'dart:typed_data'; - -/// Fetches an HTTP resource from the specified [url] using the specified [headers]. -Future httpGet(String url, {Map? headers}) async { - final HttpRequest request = await HttpRequest.request( - url, - requestHeaders: headers, - ); - return Uint8List.fromList(utf8.encode(request.responseText!)); -} diff --git a/third_party/packages/flutter_svg/lib/src/utilities/http.dart b/third_party/packages/flutter_svg/lib/src/utilities/http.dart deleted file mode 100644 index cdf44641b52a..000000000000 --- a/third_party/packages/flutter_svg/lib/src/utilities/http.dart +++ /dev/null @@ -1 +0,0 @@ -export '_http_io.dart' if (dart.library.html) '_http_web.dart'; diff --git a/third_party/packages/flutter_svg/lib/svg.dart b/third_party/packages/flutter_svg/lib/svg.dart index 785cfa146946..d39e47badfcb 100644 --- a/third_party/packages/flutter_svg/lib/svg.dart +++ b/third_party/packages/flutter_svg/lib/svg.dart @@ -2,6 +2,7 @@ import 'dart:ui' as ui; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; +import 'package:http/http.dart' as http; import 'package:vector_graphics/vector_graphics_compat.dart'; import 'src/cache.dart'; @@ -248,7 +249,13 @@ class SvgPicture extends StatelessWidget { this.clipBehavior = Clip.hardEdge, @deprecated bool cacheColorFilter = false, SvgTheme? theme, - }) : bytesLoader = SvgNetworkLoader(url, headers: headers, theme: theme), + http.Client? httpClient, + }) : bytesLoader = SvgNetworkLoader( + url, + headers: headers, + theme: theme, + httpClient: httpClient, + ), colorFilter = colorFilter ?? _getColorFilter(color, colorBlendMode), super(key: key); diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml index a5d77b936a89..4e07c613a3f6 100644 --- a/third_party/packages/flutter_svg/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -2,14 +2,15 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.9 +version: 2.0.10 dependencies: flutter: sdk: flutter - vector_graphics: ^1.1.9+1 - vector_graphics_codec: ^1.1.9+1 - vector_graphics_compiler: ^1.1.9+1 + http: ^1.2.1 + vector_graphics: ^1.1.11 + vector_graphics_codec: ^1.1.11 + vector_graphics_compiler: ^1.1.11 dev_dependencies: flutter_test: diff --git a/third_party/packages/flutter_svg/test/widget_svg_test.dart b/third_party/packages/flutter_svg/test/widget_svg_test.dart index 8913907b882f..49dfe8ed1064 100644 --- a/third_party/packages/flutter_svg/test/widget_svg_test.dart +++ b/third_party/packages/flutter_svg/test/widget_svg_test.dart @@ -1,12 +1,11 @@ -import 'dart:async'; import 'dart:convert'; -import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/widgets.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:http/http.dart' as http; class _TolerantComparator extends LocalFileComparator { _TolerantComparator(Uri testFile) : super(testFile); @@ -39,9 +38,6 @@ Future _checkWidgetAndGolden(Key key, String filename) async { } void main() { - late FakeHttpClientResponse fakeResponse; - late FakeHttpClientRequest fakeRequest; - late FakeHttpClient fakeHttpClient; final MediaQueryData mediaQueryData = MediaQueryData.fromView(PlatformDispatcher.instance.implicitView!); @@ -54,12 +50,6 @@ void main() { goldenFileComparator = newComparator; }); - setUp(() { - fakeResponse = FakeHttpClientResponse(); - fakeRequest = FakeHttpClientRequest(fakeResponse); - fakeHttpClient = FakeHttpClient(fakeRequest); - }); - testWidgets( 'SvgPicture does not use a color filtering widget when no color specified', (WidgetTester tester) async { @@ -306,40 +296,41 @@ void main() { }); testWidgets('SvgPicture.network', (WidgetTester tester) async { - await HttpOverrides.runZoned(() async { - final GlobalKey key = GlobalKey(); - await tester.pumpWidget( - MediaQuery( - data: mediaQueryData, - child: RepaintBoundary( - key: key, - child: SvgPicture.network( - 'test.svg', - ), + final GlobalKey key = GlobalKey(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: RepaintBoundary( + key: key, + child: SvgPicture.network( + 'test.svg', + httpClient: FakeHttpClient(), ), ), - ); - await tester.pumpAndSettle(); - await _checkWidgetAndGolden(key, 'flutter_logo.network.png'); - }, createHttpClient: (SecurityContext? c) => fakeHttpClient); + ), + ); + await tester.pumpAndSettle(); + await _checkWidgetAndGolden(key, 'flutter_logo.network.png'); }); testWidgets('SvgPicture.network with headers', (WidgetTester tester) async { - await HttpOverrides.runZoned(() async { - final GlobalKey key = GlobalKey(); - await tester.pumpWidget( - MediaQuery( - data: mediaQueryData, - child: RepaintBoundary( - key: key, - child: SvgPicture.network('test.svg', - headers: const {'a': 'b'}), + final GlobalKey key = GlobalKey(); + final FakeHttpClient client = FakeHttpClient(); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: RepaintBoundary( + key: key, + child: SvgPicture.network( + 'test.svg', + headers: const {'a': 'b'}, + httpClient: client, ), ), - ); - await tester.pumpAndSettle(); - expect(fakeRequest.headers['a']!.single, 'b'); - }, createHttpClient: (SecurityContext? c) => fakeHttpClient); + ), + ); + await tester.pumpAndSettle(); + expect(client.headers['a'], 'b'); }); testWidgets('SvgPicture can be created without a MediaQuery', @@ -361,19 +352,18 @@ void main() { }); testWidgets('SvgPicture.network HTTP exception', (WidgetTester tester) async { - await HttpOverrides.runZoned(() async { - expect(() async { - fakeResponse.statusCode = 400; - await tester.pumpWidget( - MediaQuery( - data: mediaQueryData, - child: SvgPicture.network( - 'notFound.svg', - ), + expect(() async { + final http.Client client = FakeHttpClient(400); + await tester.pumpWidget( + MediaQuery( + data: mediaQueryData, + child: SvgPicture.network( + 'notFound.svg', + httpClient: client, ), - ); - }, isNotNull); - }, createHttpClient: (SecurityContext? c) => fakeHttpClient); + ), + ); + }, isNotNull); }); testWidgets('SvgPicture semantics', (WidgetTester tester) async { @@ -791,65 +781,19 @@ class FakeAssetBundle extends Fake implements AssetBundle { } } -class FakeHttpClient extends Fake implements HttpClient { - FakeHttpClient(this.request); +class FakeHttpClient extends Fake implements http.Client { + FakeHttpClient([this.statusCode = 200]); - FakeHttpClientRequest request; + final int statusCode; - @override - Future getUrl(Uri url) async => request; -} - -class FakeHttpHeaders extends Fake implements HttpHeaders { - final Map values = {}; - - @override - void add(String name, Object value, {bool preserveHeaderCase = false}) { - values[name] = value.toString(); - } + final Map headers = {}; @override - List? operator [](String key) { - return [values[key]!]; - } -} - -class FakeHttpClientRequest extends Fake implements HttpClientRequest { - FakeHttpClientRequest(this.response); - - FakeHttpClientResponse response; - - @override - final HttpHeaders headers = FakeHttpHeaders(); - - @override - Future close() async => response; -} - -class FakeHttpClientResponse extends Fake implements HttpClientResponse { - @override - int statusCode = 200; - - @override - int contentLength = svgStr.length; - - @override - HttpClientResponseCompressionState get compressionState => - HttpClientResponseCompressionState.notCompressed; - - @override - StreamSubscription> listen( - void Function(List event)? onData, { - Function? onError, - void Function()? onDone, - bool? cancelOnError, - }) { - return Stream.fromIterable([svgBytes]).listen( - onData, - onDone: onDone, - onError: onError, - cancelOnError: cancelOnError, - ); + Future get(Uri url, {Map? headers}) async { + if (headers != null) { + this.headers.addAll(headers); + } + return http.Response(svgStr, statusCode); } } From 57a250f63afcca07601f7bc3b919b04c4d58c5b1 Mon Sep 17 00:00:00 2001 From: Dan Field Date: Tue, 20 Feb 2024 10:26:07 -0800 Subject: [PATCH 511/512] Relax http (#1041) * Relax http * update test package too * format; --- third_party/packages/flutter_svg/CHANGELOG.md | 4 + third_party/packages/flutter_svg/pubspec.yaml | 4 +- .../packages/flutter_svg_test/pubspec.yaml | 9 +- .../test/flutter_svg_test_test.dart | 90 +++---------------- 4 files changed, 26 insertions(+), 81 deletions(-) diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md index ea9a4e24198f..d17a8ff4c20f 100644 --- a/third_party/packages/flutter_svg/CHANGELOG.md +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGES +## 2.0.10+1 + +- Relax http dependency. + ## 2.0.10 - Use package:http for network requests, and allow injection of the client. diff --git a/third_party/packages/flutter_svg/pubspec.yaml b/third_party/packages/flutter_svg/pubspec.yaml index 4e07c613a3f6..a30078b678db 100644 --- a/third_party/packages/flutter_svg/pubspec.yaml +++ b/third_party/packages/flutter_svg/pubspec.yaml @@ -2,12 +2,12 @@ name: flutter_svg description: An SVG rendering and widget library for Flutter, which allows painting and displaying Scalable Vector Graphics 1.1 files. repository: https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 2.0.10 +version: 2.0.10+1 dependencies: flutter: sdk: flutter - http: ^1.2.1 + http: ^1.0.0 vector_graphics: ^1.1.11 vector_graphics_codec: ^1.1.11 vector_graphics_compiler: ^1.1.11 diff --git a/third_party/packages/flutter_svg_test/pubspec.yaml b/third_party/packages/flutter_svg_test/pubspec.yaml index 42877752fcf6..54a1a4265076 100644 --- a/third_party/packages/flutter_svg_test/pubspec.yaml +++ b/third_party/packages/flutter_svg_test/pubspec.yaml @@ -2,17 +2,20 @@ name: flutter_svg_test description: A testing library which makes it easy to test flutter svg . Built to be used with the flutter svg package. repository: https://github.com/dnfield/flutter_svg/tree/master/packages/flutter_svg_test issue_tracker: https://github.com/dnfield/flutter_svg/issues -version: 1.0.0 +version: 1.0.1 dependencies: flutter: sdk: flutter - flutter_svg: ^2.0.4 + flutter_svg: ^2.0.10 flutter_test: sdk: flutter +dev_dependencies: + http: ^1.0.0 + environment: sdk: '>=2.19.0-0 <4.0.0' flutter: ">=3.7.0-0" - + diff --git a/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart b/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart index 474b5e79fdb3..d00ce7a4d508 100644 --- a/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart +++ b/third_party/packages/flutter_svg_test/test/flutter_svg_test_test.dart @@ -1,4 +1,3 @@ -import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; @@ -7,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg_test/flutter_svg_test.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:http/http.dart' as http; void main() { group('finds', () { @@ -24,12 +24,14 @@ void main() { }); testWidgets('network svg', (WidgetTester widgetTester) async { - await HttpOverrides.runZoned(() async { - final SvgPicture asset = SvgPicture.network('svg.dart'); - await widgetTester.pumpWidget(asset); + final http.Client fakeClient = _FakeHttpClient(); + final SvgPicture asset = SvgPicture.network( + 'svg.dart', + httpClient: fakeClient, + ); + await widgetTester.pumpWidget(asset); - expect(find.svg(asset.bytesLoader), findsOneWidget); - }, createHttpClient: (SecurityContext? c) => _setupFakeClient); + expect(find.svg(asset.bytesLoader), findsOneWidget); }); testWidgets('string svg', (WidgetTester widgetTester) async { @@ -68,12 +70,10 @@ void main() { }); testWidgets('network svg with url', (WidgetTester widgetTester) async { - await HttpOverrides.runZoned(() async { - const String svgUri = 'svg.dart'; - await widgetTester.pumpWidget(SvgPicture.network(svgUri)); + const String svgUri = 'svg.dart'; + await widgetTester.pumpWidget(SvgPicture.network(svgUri)); - expect(find.svgNetworkWithUrl(svgUri), findsOneWidget); - }, createHttpClient: (SecurityContext? c) => _setupFakeClient); + expect(find.svgNetworkWithUrl(svgUri), findsOneWidget); }); testWidgets('file svg wit path', (WidgetTester widgetTester) async { @@ -93,13 +93,6 @@ void main() { }); } -HttpClient get _setupFakeClient { - final _FakeHttpClientResponse fakeResponse = _FakeHttpClientResponse(); - final _FakeHttpClientRequest fakeRequest = - _FakeHttpClientRequest(fakeResponse); - return _FakeHttpClient(fakeRequest); -} - class _FakeAssetBundle extends Fake implements AssetBundle { @override Future loadString(String key, {bool cache = true}) async { @@ -112,65 +105,10 @@ class _FakeAssetBundle extends Fake implements AssetBundle { } } -class _FakeHttpClient extends Fake implements HttpClient { - _FakeHttpClient(this.request); - - _FakeHttpClientRequest request; - - @override - Future getUrl(Uri url) async => request; -} - -class _FakeHttpHeaders extends Fake implements HttpHeaders { - final Map values = {}; - - @override - void add(String name, Object value, {bool preserveHeaderCase = false}) { - values[name] = value.toString(); - } - - @override - List? operator [](String key) { - return [values[key]!]; - } -} - -class _FakeHttpClientRequest extends Fake implements HttpClientRequest { - _FakeHttpClientRequest(this.response); - - _FakeHttpClientResponse response; - - @override - final HttpHeaders headers = _FakeHttpHeaders(); - - @override - Future close() async => response; -} - -class _FakeHttpClientResponse extends Fake implements HttpClientResponse { - @override - int statusCode = 200; - - @override - int contentLength = _svgStr.length; - - @override - HttpClientResponseCompressionState get compressionState => - HttpClientResponseCompressionState.notCompressed; - +class _FakeHttpClient extends Fake implements http.Client { @override - StreamSubscription> listen( - void Function(List event)? onData, { - Function? onError, - void Function()? onDone, - bool? cancelOnError, - }) { - return Stream.fromIterable([_svgBytes]).listen( - onData, - onDone: onDone, - onError: onError, - cancelOnError: cancelOnError, - ); + Future get(Uri url, {Map? headers}) async { + return http.Response(_svgStr, 200); } } From 760b8df4a7ce388ff910e4cddaea24c8de530675 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 28 Oct 2024 10:39:30 -0400 Subject: [PATCH 512/512] [flutter_svg] Initial import Imports https://github.com/dnfield/flutter_svg into this repository, with history, and updates it to follow repository conventions: - Updates min SDKs. - Removes analysis options and fixes resulting warnings. - Autoformats. - Updates pubspecs to follow repo standard. - Updates repo tooling to allow the `flutter_svg_test` non-dev dependency on `flutter_test`. - Adds repo metadata. - Adds METADATA files. - Adds commemoration to README. - Updates example app Android build files to current standards. - Bumps versions and slightly relax version constraints for vector_graphics* to allow the new versions. - Moves gitignore of golden test diffs into the package. --- .github/dependabot.yml | 11 + CODEOWNERS | 2 + README.md | 2 + script/configs/allowed_unpinned_deps.yaml | 6 + script/configs/temp_exclude_excerpt.yaml | 2 + .../tool/lib/src/license_check_command.dart | 2 + .../tool/lib/src/pubspec_check_command.dart | 6 +- third_party/packages/flutter_svg/CHANGELOG.md | 544 +++++++++--------- third_party/packages/flutter_svg/METADATA | 15 + third_party/packages/flutter_svg/README.md | 9 + .../packages/flutter_svg/dart_test.yaml | 4 + .../packages/flutter_svg/example/README.md | 7 +- .../flutter_svg/example/analysis_options.yaml | 29 - .../example/android/app/build.gradle | 9 +- .../android/app/src/debug/AndroidManifest.xml | 3 +- .../android/app/src/main/AndroidManifest.xml | 4 +- .../com/example/example/MainActivity.kt | 6 - .../plugins/fluttersvgexample/MainActivity.kt | 5 + .../app/src/profile/AndroidManifest.xml | 3 +- .../flutter_svg/example/android/build.gradle | 15 +- .../example/android/example_android.iml | 29 - .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../example/android/settings.gradle | 13 + .../packages/flutter_svg/example/example.iml | 18 - .../flutter_svg/example/example_android.iml | 27 - .../ios/Runner.xcodeproj/project.pbxproj | 6 +- .../example/ios/Runner/AppDelegate.swift | 2 +- .../flutter_svg/example/ios/Runner/main.m | 2 +- .../flutter_svg/example/lib/grid.dart | 9 +- .../flutter_svg/example/lib/main.dart | 1 + .../flutter_svg/example/linux/CMakeLists.txt | 5 +- .../flutter/generated_plugin_registrant.cc | 11 - .../flutter/generated_plugin_registrant.h | 15 - .../example/linux/my_application.cc | 38 +- .../Flutter/GeneratedPluginRegistrant.swift | 10 - .../macos/Runner/Configs/AppInfo.xcconfig | 2 +- .../packages/flutter_svg/example/pubspec.yaml | 20 +- .../flutter/generated_plugin_registrant.cc | 11 - .../flutter/generated_plugin_registrant.h | 15 - .../example/windows/runner/main.cpp | 5 +- .../example/windows/runner/resource.h | 10 +- .../example/windows/runner/run_loop.h | 6 +- .../example/windows/runner/utils.cpp | 11 +- .../example/windows/runner/win32_window.cpp | 18 +- .../example/windows/runner/win32_window.h | 9 +- .../packages/flutter_svg/flutter_svg.iml | 18 - .../flutter_svg/flutter_svg_android.iml | 27 - .../packages/flutter_svg/lib/src/cache.dart | 2 +- .../flutter_svg/lib/src/default_theme.dart | 6 +- third_party/packages/flutter_svg/lib/svg.dart | 68 +-- third_party/packages/flutter_svg/pubspec.yaml | 31 +- .../packages/flutter_svg/test/.gitignore | 2 + .../packages/flutter_svg/test/cache_test.dart | 39 +- .../flutter_svg/test/default_theme_test.dart | 18 +- .../test/no_width_height_test.dart | 8 +- .../flutter_svg/test/widget_svg_test.dart | 34 +- .../packages/flutter_svg_test/CHANGELOG.md | 12 + .../packages/flutter_svg_test/METADATA | 15 + .../packages/flutter_svg_test/README.md | 9 + .../packages/flutter_svg_test/dart_test.yaml | 4 + .../packages/flutter_svg_test/pubspec.yaml | 20 +- 61 files changed, 578 insertions(+), 714 deletions(-) create mode 100644 third_party/packages/flutter_svg/METADATA create mode 100644 third_party/packages/flutter_svg/dart_test.yaml delete mode 100644 third_party/packages/flutter_svg/example/analysis_options.yaml delete mode 100644 third_party/packages/flutter_svg/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt create mode 100644 third_party/packages/flutter_svg/example/android/app/src/main/kotlin/io/flutter/plugins/fluttersvgexample/MainActivity.kt delete mode 100644 third_party/packages/flutter_svg/example/android/example_android.iml delete mode 100644 third_party/packages/flutter_svg/example/example.iml delete mode 100644 third_party/packages/flutter_svg/example/example_android.iml delete mode 100644 third_party/packages/flutter_svg/example/linux/flutter/generated_plugin_registrant.cc delete mode 100644 third_party/packages/flutter_svg/example/linux/flutter/generated_plugin_registrant.h delete mode 100644 third_party/packages/flutter_svg/example/macos/Flutter/GeneratedPluginRegistrant.swift delete mode 100644 third_party/packages/flutter_svg/example/windows/flutter/generated_plugin_registrant.cc delete mode 100644 third_party/packages/flutter_svg/example/windows/flutter/generated_plugin_registrant.h delete mode 100644 third_party/packages/flutter_svg/flutter_svg.iml delete mode 100644 third_party/packages/flutter_svg/flutter_svg_android.iml create mode 100644 third_party/packages/flutter_svg/test/.gitignore create mode 100644 third_party/packages/flutter_svg_test/CHANGELOG.md create mode 100644 third_party/packages/flutter_svg_test/METADATA create mode 100644 third_party/packages/flutter_svg_test/dart_test.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9681048365d6..1f31d7198f59 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -886,3 +886,14 @@ updates: ignore: - dependency-name: "*" update-types: ["version-update:semver-minor", "version-update:semver-patch"] + + - package-ecosystem: "gradle" + directory: "/third_party/packages/flutter_svg/example/android/app" + commit-message: + prefix: "[flutter_svg]" + schedule: + interval: "weekly" + open-pull-requests-limit: 10 + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-minor", "version-update:semver-patch"] diff --git a/CODEOWNERS b/CODEOWNERS index 0785e52ba2cb..d6b144c1237e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -46,6 +46,8 @@ packages/webview_flutter/** @bparrishMines packages/xdg_directories/** @stuartmorgan third_party/packages/cupertino_icons/** @MitchellGoodwin third_party/packages/cupertino_icons/test/goldens/** @LongCatIsLooong +third_party/packages/flutter_svg/** @domesticmouse +third_party/packages/flutter_svg_test/** @domesticmouse third_party/packages/path_parsing/** @domesticmouse # Plugin platform implementation rules. These should stay last, since the last diff --git a/README.md b/README.md index e256308ebee0..23c16071164b 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ These are the packages hosted in this repository: | [flutter\_lints](./packages/flutter_lints/) | [![pub package](https://img.shields.io/pub/v/flutter_lints.svg)](https://pub.dev/packages/flutter_lints) | [![pub points](https://img.shields.io/pub/points/flutter_lints)](https://pub.dev/packages/flutter_lints/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_lints)](https://pub.dev/packages/flutter_lints/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_lints?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_lints) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_lints?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_lints) | | [flutter\_markdown](./packages/flutter_markdown/) | [![pub package](https://img.shields.io/pub/v/flutter_markdown.svg)](https://pub.dev/packages/flutter_markdown) | [![pub points](https://img.shields.io/pub/points/flutter_markdown)](https://pub.dev/packages/flutter_markdown/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_markdown)](https://pub.dev/packages/flutter_markdown/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_markdown?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_markdown) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_markdown?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_markdown) | | [flutter\_plugin\_android\_lifecycle](./packages/flutter_plugin_android_lifecycle/) | [![pub package](https://img.shields.io/pub/v/flutter_plugin_android_lifecycle.svg)](https://pub.dev/packages/flutter_plugin_android_lifecycle) | [![pub points](https://img.shields.io/pub/points/flutter_plugin_android_lifecycle)](https://pub.dev/packages/flutter_plugin_android_lifecycle/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_plugin_android_lifecycle)](https://pub.dev/packages/flutter_plugin_android_lifecycle/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_plugin_android_lifecycle?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_plugin_android_lifecycle) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_plugin_android_lifecycle?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_plugin_android_lifecycle) | +| [flutter\_svg](./third_party/packages/flutter_svg/) | [![pub package](https://img.shields.io/pub/v/flutter_svg.svg)](https://pub.dev/packages/flutter_svg) | [![pub points](https://img.shields.io/pub/points/flutter_svg)](https://pub.dev/packages/flutter_svg/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_svg)](https://pub.dev/packages/flutter_svg/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_svg?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_svg) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_svg?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_svg) | +| [flutter\_svg\_test](./third_party/packages/flutter_svg_test/) | [![pub package](https://img.shields.io/pub/v/flutter_svg_test.svg)](https://pub.dev/packages/flutter_svg_test) | [![pub points](https://img.shields.io/pub/points/flutter_svg_test)](https://pub.dev/packages/flutter_svg_test/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_svg_test)](https://pub.dev/packages/flutter_svg_test/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_svg_test?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_svg_test) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_svg_test?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_svg_test) | | [flutter\_template\_images](./packages/flutter_template_images/) | [![pub package](https://img.shields.io/pub/v/flutter_template_images.svg)](https://pub.dev/packages/flutter_template_images) | [![pub points](https://img.shields.io/pub/points/flutter_template_images)](https://pub.dev/packages/flutter_template_images/score) | [![popularity](https://img.shields.io/pub/popularity/flutter_template_images)](https://pub.dev/packages/flutter_template_images/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20flutter_template_images?label=)](https://github.com/flutter/flutter/labels/p%3A%20flutter_template_images) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20flutter_template_images?label=)](https://github.com/flutter/packages/labels/p%3A%20flutter_template_images) | | [go\_router](./packages/go_router/) | [![pub package](https://img.shields.io/pub/v/go_router.svg)](https://pub.dev/packages/go_router) | [![pub points](https://img.shields.io/pub/points/go_router)](https://pub.dev/packages/go_router/score) | [![popularity](https://img.shields.io/pub/popularity/go_router)](https://pub.dev/packages/go_router/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20go_router?label=)](https://github.com/flutter/flutter/labels/p%3A%20go_router) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20go_router?label=)](https://github.com/flutter/packages/labels/p%3A%20go_router) | | [go\_router\_builder](./packages/go_router_builder/) | [![pub package](https://img.shields.io/pub/v/go_router_builder.svg)](https://pub.dev/packages/go_router_builder) | [![pub points](https://img.shields.io/pub/points/go_router_builder)](https://pub.dev/packages/go_router_builder/score) | [![popularity](https://img.shields.io/pub/popularity/go_router_builder)](https://pub.dev/packages/go_router_builder/score) | [![GitHub issues by-label](https://img.shields.io/github/issues/flutter/flutter/p%3A%20go_router_builder?label=)](https://github.com/flutter/flutter/labels/p%3A%20go_router_builder) | [![GitHub pull requests by-label](https://img.shields.io/github/issues-pr/flutter/packages/p%3A%20go_router_builder?label=)](https://github.com/flutter/packages/labels/p%3A%20go_router_builder) | diff --git a/script/configs/allowed_unpinned_deps.yaml b/script/configs/allowed_unpinned_deps.yaml index fead5f119d45..8941007dfa12 100644 --- a/script/configs/allowed_unpinned_deps.yaml +++ b/script/configs/allowed_unpinned_deps.yaml @@ -6,6 +6,12 @@ ## Explicit allowances +# Temporary allowance to allow importing packages in parallel; remove once +# https://github.com/flutter/packages/pull/7941 has landed. +- vector_graphics +- vector_graphics_codec +- vector_graphics_compiler + # Owned by individual Flutter Team members. # Ideally we would not do this, since there's no clear plan for what # would happen if the individuals left the Flutter Team, and the diff --git a/script/configs/temp_exclude_excerpt.yaml b/script/configs/temp_exclude_excerpt.yaml index 25580a780f97..3d1f0e38ae9a 100644 --- a/script/configs/temp_exclude_excerpt.yaml +++ b/script/configs/temp_exclude_excerpt.yaml @@ -6,6 +6,8 @@ # TODO(stuartmorgan): Remove everything from this list. See # https://github.com/flutter/flutter/issues/102679 - espresso +- flutter_svg +- flutter_svg_test - in_app_purchase/in_app_purchase - palette_generator - pointer_interceptor diff --git a/script/tool/lib/src/license_check_command.dart b/script/tool/lib/src/license_check_command.dart index 40e716591b3a..5c401b091827 100644 --- a/script/tool/lib/src/license_check_command.dart +++ b/script/tool/lib/src/license_check_command.dart @@ -47,6 +47,8 @@ const Set _ignoredFullBasenameList = { // third_party/packages, as that is the only directory where this is allowed. const Set _unannotatedFileThirdPartyDirectories = { 'path_parsing', + 'flutter_svg', + 'flutter_svg_test', }; // Copyright and license regexes for third-party code. diff --git a/script/tool/lib/src/pubspec_check_command.dart b/script/tool/lib/src/pubspec_check_command.dart index 34aa3813a41c..6e35ca4d5e03 100644 --- a/script/tool/lib/src/pubspec_check_command.dart +++ b/script/tool/lib/src/pubspec_check_command.dart @@ -569,8 +569,10 @@ class PubspecCheckCommand extends PackageLoopingCommand { 'test', }; // Non-published packages like pigeon subpackages are allowed to violate - // the dev only dependencies rule. - if (pubspec.publishTo != 'none') { + // the dev only dependencies rule, as are packages that end in `_test` (as + // they are assumed to be intended to be used as dev_dependencies by + // clients). + if (pubspec.publishTo != 'none' && !pubspec.name.endsWith('_test')) { pubspec.dependencies.forEach((String name, Dependency dependency) { if (devOnlyDependencies.contains(name)) { misplacedDevDependencies.add(name); diff --git a/third_party/packages/flutter_svg/CHANGELOG.md b/third_party/packages/flutter_svg/CHANGELOG.md index d17a8ff4c20f..1f64d4639a56 100644 --- a/third_party/packages/flutter_svg/CHANGELOG.md +++ b/third_party/packages/flutter_svg/CHANGELOG.md @@ -1,435 +1,438 @@ -# CHANGES +## 2.0.11 + +* Transfers the package source from https://github.com/dnfield/flutter_svg + to https://github.com/flutter/packages. ## 2.0.10+1 -- Relax http dependency. +* Relax http dependency. ## 2.0.10 -- Use package:http for network requests, and allow injection of the client. -- Bump vector_graphics dependency. +* Use package:http for network requests, and allow injection of the client. +* Bump vector_graphics dependency. ## 2.0.9 -- Adds back `SvgPicture(theme:)` parameter with a deprecation. Although this +* Adds back `SvgPicture(theme:)` parameter with a deprecation. Although this parameter was inherently broken, removing it would require a major semver bump, which would cause consumers to miss out on important fixes. ## 2.0.8 -- Adds back `DefaultSvgTheme`. -- Bump vector_graphics to 1.1.9+1 -- Adds debugFillProperties -- Fix bug for cache keys. +* Adds back `DefaultSvgTheme`. +* Bump vector_graphics to 1.1.9+1 +* Adds debugFillProperties +* Fix bug for cache keys. ## 2.0.7 -- Fix broken `matchTextDirection`. +* Fix broken `matchTextDirection`. ## 2.0.6 -- Fix test-only issues with latest Flutter stable (3.10). -- Roll vector_graphics to higher minimum version. +* Fix test-only issues with latest Flutter stable (3.10). +* Roll vector_graphics to higher minimum version. ## 2.0.5 -- Allow malformed UTF-8 in loaders. -- Make the cache respect the SvgTheme and ColorMapper, if present. +* Allow malformed UTF-8 in loaders. +* Make the cache respect the SvgTheme and ColorMapper, if present. ## 2.0.4 -- Newer version of vector_graphics. -- Caching bug fix. -- Reintroduce clipBehavior. +* Newer version of vector_graphics. +* Caching bug fix. +* Reintroduce clipBehavior. ## 2.0.3 -- Require newer version of vector_graphics. -- Fix bug in cache that incorrectly fired assert. +* Require newer version of vector_graphics. +* Fix bug in cache that incorrectly fired assert. ## 2.0.2 -- Require newer version of vector_graphics with multiple fixes around +* Require newer version of vector_graphics with multiple fixes around inheritence, patterns, and currentColor handling. ## 2.0.1 -- Disable Isolate parsing in debug mode. -- Fix internal Color representation leakage from `package:vector_graphics_compiler`. +* Disable Isolate parsing in debug mode. +* Fix internal Color representation leakage from `package:vector_graphics_compiler`. ## 2.0.0+1 -- Fix bug in asset loading from packages. +* Fix bug in asset loading from packages. ## 2.0.0 -- Use parsing backend from `vector_graphics_compiler`. - - Out of order defs now supported. - - Patterns supported. - - Many optimizations added. - - **REGRESSION**: Lost support for `dx` and `dy` on `text`. See +* Use parsing backend from `vector_graphics_compiler`. + * Out of order defs now supported. + * Patterns supported. + * Many optimizations added. + * **REGRESSION**: Lost support for `dx` and `dy` on `text`. See https://github.com/dnfield/vector_graphics/issues/44 if this is important to you. -- Parse SVG data in background isolate by default. -- Use widgets/rendering strategy from `vector_graphics`. -- Much less caching. -- More tests work without special handling - most of parsing is now sync, +* Parse SVG data in background isolate by default. +* Use widgets/rendering strategy from `vector_graphics`. +* Much less caching. +* More tests work without special handling - most of parsing is now sync, and the loaders know how to avoid using `compute` in tests. For SVGs that contain images, `vg.waitForPendingDecodes` is available. **DEPRECATIONS** -- The `VectorDrawable` classes have gone away. -- The `AvdPicture` and related classes/parser have gone away. -- The `PictureCache` and `PictureStream` classes have gone away. -- The `PicturePovider` class exists only for access to a no-op cache. -- Several static members on `SvgPicture` and the `svg` utility class have gone +* The `VectorDrawable` classes have gone away. +* The `AvdPicture` and related classes/parser have gone away. +* The `PictureCache` and `PictureStream` classes have gone away. +* The `PicturePovider` class exists only for access to a no-op cache. +* Several static members on `SvgPicture` and the `svg` utility class have gone away. -- The `color` and `colorBlendMode` properties have been removed. Instead, use +* The `color` and `colorBlendMode` properties have been removed. Instead, use the `colorFilter` property. ## 1.1.6 -- Fix transforms on image tags, clipPaths. -- Avoid painting zero-width strokes. +* Fix transforms on image tags, clipPaths. +* Avoid painting zero-width strokes. ## 1.1.5 -- More permissive about color strings. +* More permissive about color strings. ## 1.1.4 -- Handle default image width/height properly. +* Handle default image width/height properly. ## 1.1.3 -- Handle `pt` values. +* Handle `pt` values. ## 1.1.2 -- Update path parsing/drawing dependencies to fix arc parsing bug. +* Update path parsing/drawing dependencies to fix arc parsing bug. ## 1.1.1+1 -- Fix regression introduced in 1.1.1 -- Update fix for fill/stroke inheritence when currentColor is specified in the +* Fix regression introduced in 1.1.1 +* Update fix for fill/stroke inheritence when currentColor is specified in the SVG but not in the theme. ## 1.1.1 -- Fix a bug introduced in 1.1.0 related to fill/stroke inheritence. -- Explicit dev_dependency on flutter_lints -- Avoid deprecated API from Flutter. +* Fix a bug introduced in 1.1.0 related to fill/stroke inheritence. +* Explicit dev_dependency on flutter_lints +* Avoid deprecated API from Flutter. ## 1.1.0 -- Respect stroke* properties when a paint definition is used for a stroke. -- Respect stroke* properties from groups with no `@stroke` property. -- Bump package versions. +* Respect stroke* properties when a paint definition is used for a stroke. +* Respect stroke* properties from groups with no `@stroke` property. +* Bump package versions. ## 1.0.3+1 -- Fix bugs in picture disposal. +* Fix bugs in picture disposal. ## 1.0.3 -- Use `longestLine` rather than `minIntrinsicWidth` to place text. -- Avoid unnecessary painting when a picture doesn't actually change in +* Use `longestLine` rather than `minIntrinsicWidth` to place text. +* Avoid unnecessary painting when a picture doesn't actually change in [RenderPicture]. ## 1.0.2 -- Avoid cache invalidation when `currentColor` or font based units are not used. -- Support `rem` units. +* Avoid cache invalidation when `currentColor` or font based units are not used. +* Support `rem` units. ## 1.0.1 -- Fix bug with incorrect fills in some cases of `` elements. -- Analysis cleanup of Dart code. -- Fix bug where self-closing `` tags could alter rendering. -- Fix bug where an invalid `@stroke-dasharray` could cause an infinite loop. -- Fix bugs related to nested `` elements in ``. -- Remove unnecessary `sync*` related code. +* Fix bug with incorrect fills in some cases of `` elements. +* Analysis cleanup of Dart code. +* Fix bug where self-closing `` tags could alter rendering. +* Fix bug where an invalid `@stroke-dasharray` could cause an infinite loop. +* Fix bugs related to nested `` elements in ``. +* Remove unnecessary `sync*` related code. ## 1.0.0 -- New widget/RenderObject implementation to avoid rebuilds/paints when +* New widget/RenderObject implementation to avoid rebuilds/paints when near or overlapping an animating widget. Also should improve raster cacheability. -- Correctly list web as a supported platform. -- Support for em/ex units. -- Stable 1.0.0 release. +* Correctly list web as a supported platform. +* Support for em/ex units. +* Stable 1.0.0 release. ## 0.23.0+1 -- Missing commit that reduced breakages introduced in 0.23.0 +* Missing commit that reduced breakages introduced in 0.23.0 ## 0.23.0 -- Support for currentColor -- Some API breaks around PictureProvider to support currentColor -- Support for `xml:space` -- Support for `text-decoration` -- Support for `font-style` +* Support for currentColor +* Some API breaks around PictureProvider to support currentColor +* Support for `xml:space` +* Support for `text-decoration` +* Support for `font-style` ## 0.22.1 -- Pick up performance improvements in path_parsing 0.2.1 -- Performance improvements in XML parsing of SVGs. +* Pick up performance improvements in path_parsing 0.2.1 +* Performance improvements in XML parsing of SVGs. ## 0.22.0 -- Expose `PictureCache` on `PictureProvider`, and deprecate +* Expose `PictureCache` on `PictureProvider`, and deprecate `PictureProvider.cacheCount` and `PictureProvider.clearCache`. This is intended to allow users to set a maximum cache size, which was previously impossible. ## 0.21.0+1 -- Fix alignment/sizing issues introduced in 0.21.0 +* Fix alignment/sizing issues introduced in 0.21.0 ## 0.21.0 -- Stable nullsafe release. +* Stable nullsafe release. ## 0.21.0-nullsafety.1 -- Fix bug introduced when width and height are both null on the widget. -- Use more efficient method for XML attribute parsing. +* Fix bug introduced when width and height are both null on the widget. +* Use more efficient method for XML attribute parsing. ## 0.21.0-nullsafety.0 -- Fix sizing when both width and height are null. This is potentially breaking. -- Bump versions to stable nullsafe when possible -- Update README with links to alternative implementations of SVG in Flutter. -- Attempt to report file source/key when errors happen. -- Add missing platforms to example project, update Android embedding. -- Minor fixes for future error handling to respect new Dart rules/expectations. +* Fix sizing when both width and height are null. This is potentially breaking. +* Bump versions to stable nullsafe when possible +* Update README with links to alternative implementations of SVG in Flutter. +* Attempt to report file source/key when errors happen. +* Add missing platforms to example project, update Android embedding. +* Minor fixes for future error handling to respect new Dart rules/expectations. ## 0.20.0-nullsafety.4 -- Adds option `warningsAsErrors` that throws errors when detecting unsupported +* Adds option `warningsAsErrors` that throws errors when detecting unsupported SVG elements. ## 0.20.0-nullsafety.3 -- Fix broken image for pub. +* Fix broken image for pub. ## 0.20.0-nullsafety.2 -- Fix bug where HTTP headers were not passed along to the HTTP client. +* Fix bug where HTTP headers were not passed along to the HTTP client. ## 0.20.0-nullsafety.1 -- Remove unnecessary package:collection dependency +* Remove unnecessary package:collection dependency ## 0.20.0-nullsafety.0 -- Initial release with null safety -- Remove dead code -- Fix up incorrect `catchError` usages +* Initial release with null safety +* Remove dead code +* Fix up incorrect `catchError` usages ## 0.19.2+1 -- Fix a bug where color filters were applied when they should not be. +* Fix a bug where color filters were applied when they should not be. ## 0.19.2 -- Allow for opt-in/out of color filter caching behavior, undeprecate color +* Allow for opt-in/out of color filter caching behavior, undeprecate color filtering on the providers, and allow for a global override. ## 0.19.1 -- Fix color filtering when BlendMode.color is used. +* Fix color filtering when BlendMode.color is used. ## 0.19.0 -- Avoid unnecessary cache invalidation of SVGs drawn with color changes by: - - Deprecate color filter related options on PictureProvider classes. - - Make ColorFilter a property on SvgPicture - - Use the ColorFiltered widget for filtered SVGs. -- Fix RTL rendering bug +* Avoid unnecessary cache invalidation of SVGs drawn with color changes by: + * Deprecate color filter related options on PictureProvider classes. + * Make ColorFilter a property on SvgPicture + * Use the ColorFiltered widget for filtered SVGs. +* Fix RTL rendering bug ## 0.18.1 -- Bump the path_drawing dependency to 0.4.1+1 -- Expose clipBehavior from FittedBox -- Expose SVG ids in `Drawable*` classes. -- Change type of `alignment` to `AlignmentGeometry` on `SvgPicture`. -- Fixed bug in transform parsing +* Bump the path_drawing dependency to 0.4.1+1 +* Expose clipBehavior from FittedBox +* Expose SVG ids in `Drawable*` classes. +* Change type of `alignment` to `AlignmentGeometry` on `SvgPicture`. +* Fixed bug in transform parsing ## 0.18.0 -- Drop DiagnosticbleMixin usage. -- Bump XML dependency to ^4.1.0 and resolve deprecated API usages. -- Await futures in tests. +* Drop DiagnosticbleMixin usage. +* Bump XML dependency to ^4.1.0 and resolve deprecated API usages. +* Await futures in tests. ## 0.17.4 -- Allow `precachePicture` to take `null` for a `BuildContext`. -- Provide a clearer error message when nested `` elements are used. +* Allow `precachePicture` to take `null` for a `BuildContext`. +* Provide a clearer error message when nested `` elements are used. ## 0.17.3+1 -- Fixed regression in v0.17.3 for shape elements with no explicit fill but +* Fixed regression in v0.17.3 for shape elements with no explicit fill but explicit opacity. ## 0.17.3 -- Be more permissive about whitespace in transform attributes. -- Stop defaulting color to black when not present, fixing issue with colors +* Be more permissive about whitespace in transform attributes. +* Stop defaulting color to black when not present, fixing issue with colors carried over from `use` elements. ## 0.17.2 -- Bumped minimum Flutter version to 1.6.7 to pick up DiagnosticableMixin. -- Allow more variations of whitespace in base64 encoded image data. +* Bumped minimum Flutter version to 1.6.7 to pick up DiagnosticableMixin. +* Allow more variations of whitespace in base64 encoded image data. ## 0.17.1 -- Fix for issue with `use` elements refering to groups or other `use` elements +* Fix for issue with `use` elements refering to groups or other `use` elements not correctly applying styles. ## 0.17.0 -- Make ColorFiltering apply to whole layer instead of per paint operation. -- **BREAKING** Remove `colorFilter` parameter from `VectorDrawable.draw`. -- Fix color filtering for text. +* Make ColorFiltering apply to whole layer instead of per paint operation. +* **BREAKING** Remove `colorFilter` parameter from `VectorDrawable.draw`. +* Fix color filtering for text. ## 0.16.1 -- Support `image` tags in `defs`. -- Make `DrawableRasterImage` implement `DrawableStyleable`. +* Support `image` tags in `defs`. +* Make `DrawableRasterImage` implement `DrawableStyleable`. ## 0.16.0 -- Move `transform` out of `DrawableStyle` and onto `DrawableStyleable`. Shapes +* Move `transform` out of `DrawableStyle` and onto `DrawableStyleable`. Shapes already worked this way, and the transform logic was handled in a confusingly different way than all the other style attributes. -- Support `` elements having `id`s. -- Properly apply transforms to referenced use eleemnts. +* Support `` elements having `id`s. +* Properly apply transforms to referenced use eleemnts. ## 0.15.0 -- Respect transformations on `` tags. -- Be more tolerant of malformed base64 data, similar to browsers (specifically, +* Respect transformations on `` tags. +* Be more tolerant of malformed base64 data, similar to browsers (specifically, having spaces present in the data). ## 0.14.4 -- Apply masks in the correct order when blend modes are involved in shapes. +* Apply masks in the correct order when blend modes are involved in shapes. ## 0.14.4 -- Support for masks on groups. -- Update example project to Android X. +* Support for masks on groups. +* Update example project to Android X. ## 0.14.3 -- Support for the `mix-blend-mode` attribute. +* Support for the `mix-blend-mode` attribute. ## 0.14.2 -- Format, open up obtainKey for testing. +* Format, open up obtainKey for testing. ## 0.14.1 -- Support for HSL colors (thanks to [@christianalfoni](https://github.com/christianalfoni)) +* Support for HSL colors (thanks to [@christianalfoni](https://github.com/christianalfoni)) ## 0.14.0 -- Added support for masks (thanks to [@krispypen](https://github.com/krispypen)) -- Allow for clearing of the picture cache +* Added support for masks (thanks to [@krispypen](https://github.com/krispypen)) +* Allow for clearing of the picture cache ## 0.13.1 -- Fix case where color filters were incorrectly getting created. +* Fix case where color filters were incorrectly getting created. ## 0.13.0+2 -- Same fix for group opacity/saveLayer as in 0.12.4+2 +* Same fix for group opacity/saveLayer as in 0.12.4+2 ## 0.13.0+1 -- Bump path_drawing dependency, which includes bug fixes in parsing. +* Bump path_drawing dependency, which includes bug fixes in parsing. ## 0.13.0 -- Updated SDK constraint to support new error message formats -- Updated error message formats -- Misc. updates for new SDK features +* Updated SDK constraint to support new error message formats +* Updated error message formats +* Misc. updates for new SDK features ## 0.12.4+2 -- Changed version constraint to prevent pulling down from wrong flutter version. -- Fixed group opacity/saveLayer bug. +* Changed version constraint to prevent pulling down from wrong flutter version. +* Fixed group opacity/saveLayer bug. ## 0.12.4+1 -- Bump dep on path_drawing which contains bugfixes for parsing. +* Bump dep on path_drawing which contains bugfixes for parsing. ## 0.12.4 -- Fixed `opacity` handling, particularly for groups. Previously, opacities were +* Fixed `opacity` handling, particularly for groups. Previously, opacities were averaged together, which resulted in incorrect compositing (particularly if overlapping shapes were drawn within a group). Now, a new layer is created with the opacity applied to the whole. This may cause some performance degredation, but is more correct. -- Allow font-size to be specified in `px` (with an explicit postfix). -- Add `excludeFromSemantics` property for purely decorative SVGs. The default +* Allow font-size to be specified in `px` (with an explicit postfix). +* Add `excludeFromSemantics` property for purely decorative SVGs. The default value is false. ## 0.12.3 -- Fixed bug with stream completer unregistration. -- Fixed bug with text transforms in new parsing. -- Fixed bug with RGBA parsing for opacity +* Fixed bug with stream completer unregistration. +* Fixed bug with text transforms in new parsing. +* Fixed bug with RGBA parsing for opacity ## 0.12.2 -- Fixed bug with AVD parsing from strings. +* Fixed bug with AVD parsing from strings. ## 0.12.1 -- Support for `display="none"` and `visibility="hidden"`. +* Support for `display="none"` and `visibility="hidden"`. ## 0.12.0 -- **BREAKING** Avoid scaling based on devicePixelRatio. This turned out to be a +* **BREAKING** Avoid scaling based on devicePixelRatio. This turned out to be a mistake, and caused rendering inconsistencies across devices. It was particularly harmful on devices where the ratio was less than 1.0. -- Add `precachePicture` method to allow for pre-caching of SVG assets. Similar +* Add `precachePicture` method to allow for pre-caching of SVG assets. Similar in functionality to `precacheImage` in the Flutter framework. Also added improvements to error handling in the various related routines. ## 0.11.0+1 -- Format source code -- Remove unintentionally committed pubspec.lock +* Format source code +* Remove unintentionally committed pubspec.lock ## 0.11.0 -- Rewrote parsing logic to unpin dart-xml dependency, and bumped Dart XML +* Rewrote parsing logic to unpin dart-xml dependency, and bumped Dart XML dependency. -- Fix bug where unsupported elements could impact drawing. Unhandled elements +* Fix bug where unsupported elements could impact drawing. Unhandled elements that have children will now be completely ignored. This is technically a breaking change, as previously a child of an unsupported element could have been drawn if it was supported. Fixes [#126](https://github.com/dnfield/flutter_svg/issues/126). ## 0.10.4 -- Fix bug in transform logic [#122](https://github.com/dnfield/flutter_svg/issues/122) -- Avoid defaulting to the rootBundle, using th DefaultAssetBundle instead when +* Fix bug in transform logic [#122](https://github.com/dnfield/flutter_svg/issues/122) +* Avoid defaulting to the rootBundle, using th DefaultAssetBundle instead when resolving pictures [#118](https://github.com/dnfield/flutter_svg/pull/118) ## 0.10.3 -- Pin dart-xml to 3.2.5, as 3.3.0 is a breaking change (next release will +* Pin dart-xml to 3.2.5, as 3.3.0 is a breaking change (next release will address this). -- Support `px` postfixes on many double literals. +* Support `px` postfixes on many double literals. ## 0.10.2 -- Added a `semanticsLabel` property to `SvgPicture`. -- Updated tests to support async changes in Flutter's `Picture.toImage` method. - - This is breaking for tests - tests will now require a more recent version of +* Added a `semanticsLabel` property to `SvgPicture`. +* Updated tests to support async changes in Flutter's `Picture.toImage` method. + * This is breaking for tests - tests will now require a more recent version of Flutter to run. It should not break consumers though. ## 0.10.1 @@ -439,253 +442,252 @@ v0.10.0. Rather than splitting the breaking parts out in to v0.11.0 so soon after the release of v0.10.0, I'm including some more breaking changes here. This will not normally be done. -- Fix bug that caused `` elements that weren't self-closing to parse +* Fix bug that caused `` elements that weren't self-closing to parse improperly. -- Many documentation updates/improvements. -- Added support for gradients that use `xlink:href` -- **BREAKING**: Changed some of the methods on `DrawableDefinitionServer` to +* Many documentation updates/improvements. +* Added support for gradients that use `xlink:href` +* **BREAKING**: Changed some of the methods on `DrawableDefinitionServer` to support gradients better. -- **BREAKING**: Removed the `PaintServer` typedef, since this was only serving +* **BREAKING**: Removed the `PaintServer` typedef, since this was only serving gradients and we need to have more control there for `xlink:href` support. ## 0.10.0+1 -- Fix bug that caused an empty `` element prevent rendering. +* Fix bug that caused an empty `` element prevent rendering. ## 0.10.0 -- Rewrite parsing to be more space efficient. -- Refactor parsing to enable more output possibilities. -- Create a dedicated SVG parsing class (SvgParser). -- Updates to text - better support for nested text/tspans. -- Miscellaneous bug fixes. -- Testing improvements. +* Rewrite parsing to be more space efficient. +* Refactor parsing to enable more output possibilities. +* Create a dedicated SVG parsing class (SvgParser). +* Updates to text - better support for nested text/tspans. +* Miscellaneous bug fixes. +* Testing improvements. ## 0.9.0+1 -- Fix inheritance issues with `text-anchor`. -- Fix a few inconsistencies in text anchor processing/positioning. +* Fix inheritance issues with `text-anchor`. +* Fix a few inconsistencies in text anchor processing/positioning. ## 0.9.0 -- **BREAKING** Improvements to text positioning. Thanks to @krispypen! +* **BREAKING** Improvements to text positioning. Thanks to @krispypen! ## 0.8.3 -- Implement support for `clipPath` outside of `defs` eleemnts. -- Implement support for `use` in a `clipPath`. -- Recommend `usvg` rather than `svgcleaner` per author's recommendation. +* Implement support for `clipPath` outside of `defs` eleemnts. +* Implement support for `use` in a `clipPath`. +* Recommend `usvg` rather than `svgcleaner` per author's recommendation. ## 0.8.2 -- Make `DrawableNoop` implement `DrawableStyleable` to avoid crashing with +* Make `DrawableNoop` implement `DrawableStyleable` to avoid crashing with certain unhandled elements. -- Improve error reporting for certain `

p1Z8@r}D;G`|Ypao%l000;fn)gI_?H+^6vo(O%*ODX z_c`kjL43Iy#gedI%5hRMGVz3l#Z9Up0gD`c^1cJ|3a`&R%;MkB$Rh!fl*Ii}-fL0D z2P;|sX6%nxk1F~&UOTG(LFo64<0KXaaf+n#JGUq0O>PkxDIX*-pOxrB&~U2O9kAa9 z;PkTh_?VG{lhYHNf0X^t-tXJ5j$;7>kn#ft>%S}xmlubf7x@M-zo90ih3SN zAZ}4sO_h?+cPDg-gGpLrl2;+(BB4JRu^Z$}^ b?62pk`6dtq4|6|ZN(AUVGSX_+aEkjM!zlFR literal 4616 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 Ua_W>q;!m;2iE@^B-6AG4M@-}OmRfV* zXAtxb({VtK8-90AshMM+S;AKIzPtP1J?gXe?Lz8Ta?zbczxTOS&ES43Jglr4)zV5z z;`gUq1ulOGYE)NOXG{-YW{hQKWibI&Nzq}YGzIF@OdJ;(Yow~!aMC5}`?<+X1`tuw zXHj8vD~0Xx>1kPOD@$BlTxzE#aPSkq1GKcY(~srt9ULZSg1!6ZLM12iHMv3uDm%#D zl7p14pZ@C!u9v!N0@>dP(viUcL6`wB*#A^Q67H*RIsEmH7CZ0>B@)w>2r(dR0=FoOv{f{QQK;J1nP;~iHsj=3`h zG`-HXbaYZM?)jq$Kz*}{iJ=+wwny_5YimUT>YMeDp}BRdw6~Yr#>R%o=C3$ucxa6d zJ4gtl8#H3{QPe;c$IL(<{c_GYiO&aS#?ByKiBF5zd(#MDxuc_FTNZYD8l3y_VoSl=i?Kgw+kok#QLuQNvNw`{`V{81{KBa(%QcG7C z0;J$H+&c06Jd8sj#1M}^3Sb}yHI_D28CvRXjB8f}QBNXWGIg{0ywSkmY=ayl7Fs-Qk!w$3*wUt^W0pg8&0&jgb=*%Oo0ypVE|w&J zNvF{J>&)V~5Vi5onM)R>LiPvC-5K|P0<`;WB%pv%F!klwa zj@$q2oJx*1HR-u3_UBOxD7GYj*-+p;-?3s#0g5u20PgUIuVdh&ZGk)4pFJi^H6pn? zyStYTJP!mjZpV*b3sZ+*g?-S~QYi4~r%8@jV2X#HO@)nQF>enfGs=Y;pR4Bpz^8CL z0m<-dPsalawm0oSsrhwBhK(OV4`IZRfx`WmF(ibZLPNTCKla0ifBg~?77;nbTG(kX zPq{VEHoeN+4YGop8*h12bOKexBK{nA)lX;AXk~QRZn@8!rzf(0_Gy9JdvhO%2A|TB zf03hryPMlrK%Iz$`%%S4!>wC|mn%MmGn5gi)TI*=6Aw{>MQ>hL*UGm`fTS}86_uV% zD&B4J-E4mpX|vyVsw)Y3b>G=#CHB~vjiP1i^-Rhf(k>{Zz!A< zAJN`yPfG@=*w_>paPGy#5Sf~qRuvXL_^>gJ1S%PW@BS28;9^gUsyIzkYqC_JJ^uGt zrZoGKbS6hU@k!O-d)-WHuGhWoL3o}(NF(8ckT!P)v-iTwq63jm~(-oFoIlf11# zkHunVTRijEe?*xvA^;J2X^;b@lR310qq8gMTO7B3wO3?moRTEDTJzght0H^{;l0um zy)OX($6zXKQLH)tPIMZ;x z&dpXv*4A(5=dH{L+5ih?i&^6U;yO3oejy?vg3Np9a`&=qdD#|VN6n*9Bc|?arKCoE z-L0RpK&f$AF?EhCeQ`E8^BpR>prQc1NlbJg;P*1a zTJ}FZ_BXV(ja(TS3apsfIo!xJIB$AC?!ROwo*TEwMZN6$$YHVKDtI#PL`y0vw8OU zM52xDZT|cBQ3rc~7=9_q`a+VG_{tLwkSdT2WyQrHKv}wacpS@pSi0hREqyz$srKo+xdaRt5W7#<$x2V_IT7e_F{3hwIe?tf7W0dxRBG~d5}=b`+%K}@U{ zp`~D!O;nb8RKIpNqU?vP^iWrN<&VTX+RS1R;y3E{IS#}Qi_AgLp4;$yxy9DJg!1#qL7{C z7gUmoiApu1cHI&3)zGkt?6SQK552%J1uZ5MYtU&-5@??>0$s!Z$xvrer)@FUgl@Jm R;BO8{TjQzv7qu6${{uHQyIBAL diff --git a/third_party/golden/deborah_ufw/new-action-expander.png b/third_party/golden/deborah_ufw/new-action-expander.png index de6f20950783acaeda2152fd9068b8692c4650e8..d75da023af0f69c1e10b138aae6af50aad91562d 100644 GIT binary patch delta 4634 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 Fe*h3cy@vn* literal 8428 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 nheu$b_e+hoo&Rgd9{+u*7+bPS5u)sp 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 LZz+{2Scd&Cn`;TY diff --git a/third_party/golden/deborah_ufw/new-gif-button.png b/third_party/golden/deborah_ufw/new-gif-button.png index d941059fe957a193f5a8cda1ab753b506918d00f..84c181336e4bec6b711f6c0fccbdd03f1c9f9244 100644 GIT binary patch literal 5167 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 literal 8612 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 Vvl&~9@T3JoOI=s3LgilA{{yECY)AkA diff --git a/third_party/golden/deborah_ufw/new-gif.png b/third_party/golden/deborah_ufw/new-gif.png index 6cbc72d5ad60eb750bbbda0e4b5c8d118d3992f2..7ccc6719cab39f787052016df29e33ddb6f07099 100644 GIT binary patch literal 3143 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 literal 4813 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 SXu&Nhh=!W3Dqi_<@V@}S9WU|# diff --git a/third_party/golden/deborah_ufw/new-image.png b/third_party/golden/deborah_ufw/new-image.png index ee0373158010216661cdad990999d66ab1dca85e..ea30712bf45bb01dbc7c6ea67983be565eb84f43 100644 GIT binary patch literal 4493 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 literal 8258 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 diff --git a/third_party/golden/deborah_ufw/new-pause-button.png b/third_party/golden/deborah_ufw/new-pause-button.png index 37b1f5ee6d33463582f85c5d2aa72ca79355f567..d006e341644401b843cf1b62d3019c0963edfb24 100644 GIT binary patch literal 4513 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 diff --git a/third_party/golden/deborah_ufw/new-play-button.png b/third_party/golden/deborah_ufw/new-play-button.png index d4e5a90b1be6befaa681e0acf91ecc45a1c0f282..31320275ffc08651cbd71825ab68f88af8c52c13 100644 GIT binary patch delta 4675 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 literal 7742 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 S{rPqVjG-*AE>|gI5%xdLb+vc^ diff --git a/third_party/golden/deborah_ufw/new-send-circle.png b/third_party/golden/deborah_ufw/new-send-circle.png index d9c4f23c900752697a5f2c0a1c05232d2f78f724..4c96f358a27ca8106bc63c69b2d1736467dda575 100644 GIT binary patch literal 5591 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 literal 10504 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 literal 2809 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 A$p8QV diff --git a/third_party/golden/flutter_logo.png b/third_party/golden/flutter_logo.png index b02fbbf748009aca86896f25b4eda94ff30fb962..249a4a90605280ffa2c994c758019088fa494d77 100644 GIT binary patch literal 2763 zcmaKuk3UoUAIHyFGr!h0Q(@Szi%__vGpS~6wn-{UD%C=XB8%iE+L#=RVa4qh`6k_) zLQ?66Zg;nh=2wd-O5qTxo23*AeUJMG-1B&R-k)<`=kAR925zffYu#~tKn*GPv1SbP6 zv8{4u5x?tH%+KtXjL_ye2_v$~;6I5z)M-h*Si>KEh0+be{Q z`ttR!Y*wsxk)ZJ+(n5(tE-1@kk$B{K9>tH2TTXx;LaH6;QfD~MO5z{`dk~q1TTOt{ zAk{83%^Ut`CBe$UX&!}5$5{{{CA200O>>6x%q3VEILM{2X}I4AkQiDMi-wtSp0y+? z8yw_O&eL$#1Sk_)vmOnD@Dpc=q+}IpV&%BB$1RL zA>l<*Gf9XXd?;f%`;z;)ltP-^m5w(i@a_;a5P{c4&|nF?NrEPiz+=+#s5JQ}4n^OW z{6@yYKw#5C$+(5+w7cF29dQ)P z1ZCQh?kv?#b-&#Nov*690EoK$h&ZKN-qHF5m(-p+ z-ZA}z%;K_sz`KHSfl9@#5U5c}-$+g*hI+SsISAxxeQwg{t!9}l3Pq)Wkn%H|nR&{&G?oWl&q!sA&>iE#BPPqNsRBKDq(%K-ri3t;jg zRlqh8z?J~B`S{FYj{yL!kD8{6vIbiB`jOMjRv&uK4~4-W!3McSXH}zy7P{L97U?OAO~t zs`JhD6i?!SCNc0epRdfnWFde+AcF-Y^BMh`c8C!~76($4Z}|*Z(=KI1ki}sXLtVQ2R8WvdXeSK-u)P)??iS3XB;Dsg17PbpKN?Zq=dvi@@O8%IIpH ze9^W0BSS0X1#s8FY^M7=pP(IMlujo*K3V*-fU_94zu@zgB}10HLSx3BM<~38KlLzw zGlK}f4IaH}OYH?~WGpthS%f*kHE=KgL8o%I`Er zmfA*M=3VI1Y|D~@n3Fd;F51tw8DV(Oz68tuT0RtaaQ|5l1G#rz)TJIZNw!y=J$v+~ zxS?@i@>%%$f%3@Nkz_F1=>2A4dCcbY^b$h@!OCq)t3OiHjfeN*d2TiK#9Q7bz|B=n^|M|s^rHLAJu<+A6;0K$T4l$lqQX=%xnynWA}>^){YgdIj*`s{QIlMgWqHq-P8ThZvTauIR)X&bP{I%y5c2Eh8T+i}xOGGtIib&W1gljV5M$UOKwBH?{dlJ$B@V z#q8m*DTPi(jUmIB$20KDW)O~u+I}nh;tvxq=z3o8lK`i;WrX%sKaO|j;rXa;-=Axf z^nav&+87$+f#;63uD>G0Y-f61{$GaW&{MA$QHP_}dM52*vnliT7z+-MVRp_=Esy(h z=we;5tgtt4;&W7Isl}S+?2A!$Zn>2qoJ+b++O--AHBZmV{9pUG5me}Y523%wss64( zCht*Dn_sMt`(4w|ZHxu}twyq21t>!asi&GB3x{lD`jhnScD@L%JbwL1spX5#iLk0f z`=Kkh!>KRsNiTP?d29;KlGGSYZj()ruWpfhSgPQ{SNn2$)1MXARd48)bOagwS-3MJ zTgoDLx+rde_g-Ex$wa|kUfUBd+!zQCIWz6B;885sa;#3hGfkdn zvi^h;U*{$a&+zS6i9NdCC5@k3NK>dMfTrLRgUZjJ&!q03(t_7i`5pLNoo`Lb{OUKJ zUEjathb8ZO=M3~ow4-0Vi7Sv__A}butnjZ!iVsI<=eu$uV4PBY^?}f5EtT58pm~#p zqVBe*sDF}r-|a_i$3!Zsb0Q^hnY>~{?RGSL9rDoN+ER$LN_!KB4_h^5SdOypa+J^Cb67fIDrSyL>4D76iq}>(m(h?^|EzO zQ-FY%-~y}4+t+S??CaQiKjqIi$qpIgDudPX`MOta+SRZA?Y&c2X~tP|N>7;Ee{$O# b(>?ux8W@M0l~nW*1V{k^H-J;c7N-3l2=~9n delta 2950 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 KQ_F4ruKX8R_(0bH diff --git a/third_party/golden/simple/clip_path.png b/third_party/golden/simple/clip_path.png index 559d1b04993a68e6a66bf76ae0efe06c58a32a84..b43af6829e4a63715e809ccd72710bfe8bcc6d9f 100644 GIT binary patch literal 2618 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 APyhe` diff --git a/third_party/golden/simple/clip_path_2.png b/third_party/golden/simple/clip_path_2.png index 975b95b77aaa383bdfb2efccdc7f0d6f293c106b..47af8b9732fd1de0e110c409d7c0ae5bc376234e 100644 GIT binary patch delta 2082 zcmV+-2;KMT7~c_)KvxKfNklnn zlTHR0e^_0R>2xZ+UXR>yrqikEVW!oy@k<-xIF{ePe@hsKrY{98@O@w2-rmG<9MhNb zgLN}V7=|(!3@As3*!*v9RYA7ftqg}liR0MxrJ!Y}Rl|0>HGL`PlqKf#xe^gV)O5XwQS#6(G2Ey&Bui}4>ax$U&Qac`|4+^r&YrOlGG zQjpnfX8ear?kls|tc{`Dd_gvwjqx8QxzB7io2G|vvjw3Xr0FzWlEw=1_V#A{hex`R zf48@{riQU<$0fDK&Nl^_Ue+mFs-Ci!USchmOUeQ3#c?dl<+A(>l$mydATU045>g~V z5R_VCl`6<+G&24dCZtG4qft8rVPj5iHDxyJg*NGI%yG-gY}gBJ(%0)X<-pB~f8$uz z>vf_3C-)4(?16hwbQZ}ygD`vG9>j56=ouurXOO{QAW;;RzA(TRuItL-aLDz0bIl;z z?Ur)jZbVU(dltzxgD`vG-sGJ{uFfFL9=J!jXOU|MC43t@x!3r?f7h>Hja(F9ljHH2d2pCHgY0&@#x4l3iEgZC7Ub{W zzl~fBU>jXQQkPg!6v<#PX!N20n;Z@Yab5Svucyu+EU(ZtnPZ-_4??ofM1B;6&zqC3 z=5RP%KL_FL16`H&VX7Ym`STCo-DL;9_aN*)fKSPN$oCAw@(TEr>;eS=E~FNO{Ri+V*@d1`O0oX{&Ykul z4p`BaPDl0_3`mx^kM+pyuZJT$k$!0Uax2P zasc}%rR0JA2aqm`A_@Xz7Kx%r9ykL5(uHA|{|Qq-7ZrNSEzmWQ(K3@x1`2=9YPB-{ z0Cz%c%xbk#55DgUfS-Kdmj~B%OQNwzQtES)?s=Z+YXPkC^zr_+D_LnJYSunz&w_a7n`p9f)?g|55o00jXOE<14c5Ks0Y z=(^q!5xVL@A{_&oh3p zgtQsY^U|uIQor_RGMS|PGH|!D#{Ah`tdl5;WH1;seo=re4u?bP$3A~jXAswQzdw@; z+`H%J=giMUWqz|F%Pe%o%gamVe@k6riEwC$?zlW0Ov;==9LJIIc-+`U0X7(q$C>32 zx$@=JEVFR$u8#54o4=fikPhVO>FL_=Pd^7qn$PFgehYAu@~n_DH|a^P>&pB4do33Q z*x>Q;QKBfi`ulP{KxcosTvomyz$SUebgmghgjodlBk$}XQs5D6>_u=dij3vlGe{iA z;<~PUe0-F?Fu=5azb{b~Y0o~Aa?c=+<1mZh=FR8x+~p7{FoTFNi{Q2uojpVfJ_g!x z99gf|g)a=S!Fs(eR1Oi5t0(Dco}QkJpMnxnBzaEF)08R*pId(?x0WCX+AD}sO3h|7 z<9}&F@?f;p-p-c8+P1+QXBK6(sR!jHtfXKl--!uvcx(G z!%&99VU?Ev8W99RGr{M+w8Q+QvMg@)GOBaU9uhw{^W7P|9w%tF0U&BDF2C zP8N%W@hO&cGmFKd?%`biBwdGFzohNdaZ5K%ZF`U;PTA3>s;A{Twe3NY9LJH}Zr8+1 z13%Qh??`H7Uiz}xY>ZF6Ux&Fn#vC<$pQO_zT|sTK;N6mN|u^{2{P*o$bT zAWA7U9*>RxP|1B{JRY|-Y}+e{Qj~;LPn+dXs^x+lk4L^Oo|KN~dFpsPwmD?mEr?Q- zgp`Ykawuh>AWBgZQY@y*p;V6NgEYZ$9NF*p;(4BlKOQ&4^E}z__styyUSXslBA+D* z!;t47BGZ3(Jg)Vv>!lc(w=QsZi(IDdyH#1ND2P%VCX)Zt)*)aX))Yi3-j>q!^!xo* z-ab-9BX4)FA`C+rjYhmxzGM3RzU=q=dcJ6(M#eVjS$yA@D2lkl)ghkeNfbral|#hB zf{1X3t4pl7Q>9_u5(}`2l`{xn3km{gP!K?af&i0I1|pMK1`!tHKNo1O05i(F4gdfE M07*qoM6N<$g2>eTcmMzZ delta 2985 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 U-cwU7;Q%l5o7Se)Chpk(0bT9-HUIzs diff --git a/third_party/golden/simple/clip_path_3.png b/third_party/golden/simple/clip_path_3.png index 76fed26010ebcc53e58ac640faba36070223a17d..1e1698f993d10ccec470e4baefddbf2bb1178a65 100644 GIT binary patch literal 2691 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 diff --git a/third_party/golden/simple/dash_path.png b/third_party/golden/simple/dash_path.png index 3774e3677ee77480890c6a5573a8ed4f8fbbdbc3..79c855ce509992e9e752557bdb38b7a6ec61bcbc 100644 GIT binary patch delta 412 zcmX@ZHj8b7W9ku47srr_IdAVe=FJWeaR^+o$za;Cb8qJE-0ah}ex9?`^jC8fA8{{w z@rrkn`nBVaKSne-@4xq#>4Uy72TP-a020yC|FZY>u78DZU*z|^E50xKZnlx5!kT|q zS>_o}e!!$9So7O&*XDC^58q7TWIE_)#Ueb}kWpoF03#dU%DG>ZFXx9_zkXwV-f!k) zUM2&-8#1#jz@@usm+HdV)FwjO_JEpL1Hymk4}`Q@ir z8WYrIn>Z(LWD=gdfk{M!h3Vn`o1Wk6?!A|^e)(ZK%tm>jjTm z1v0w!Z`TxNX_{NYp*ES3QFP*85y_Td>zC)hty%v2`Z??W>pow0jY2387W={5nD6sM TTgTLi0SG)@{an^LB{Ts5@FTt3 literal 844 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 delta 4166 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 QYXATM07*qoM6N<$f&-66=l}o! diff --git a/third_party/golden/simple/group_fill_opacity.png b/third_party/golden/simple/group_fill_opacity.png index 3cb70c6522d9a12441cbc065a40553180868b276..db3b4438ea100b9d90e08fe5916fe47eb7b344c9 100644 GIT binary patch literal 5155 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 Q^g$n>rlhS{C2tk+FAL$6wg3PC literal 6546 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 diff --git a/third_party/golden/simple/group_opacity.png b/third_party/golden/simple/group_opacity.png index 75bde900629b0ea493419384a96c26b0294ac333..46c5bdb95dd9baf1649ce26df4c422ac45d34b91 100644 GIT binary patch literal 4157 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 XdYpPR1SkK#3jn5umY`aFxA^}6Ho7%< diff --git a/third_party/golden/simple/linear_gradient.png b/third_party/golden/simple/linear_gradient.png index 8d84b321b9e7bc192bc7a7d8296735e8b9c20c80..2df89ef0c4295c366898623bf75a3b4982492ede 100644 GIT binary patch literal 1838 zcma)7Yfuwc6b|bGF@h#a>f$R)gb|5a7f?~uBs2kH9V@64N+VFi_y9!27gjTpC>U@d zkq$}=gBGlnhe1FzQ4kRfQB<0-m8w)wKoAr~kcR==dpC@K+stgvp4az%=j@%iDeKn- zI5K81Xf&FmBv2F#tO-7JJMe!oM3)PU&7R-@Kbr2rtXIH6_xMRR(!uXAJyK1h+5IIE z2{$I>ylE1~&Xh96=9YLZ?M|KGrA?VCa^hfcc}9%zS(4Yo-{uQ)46?Jjd+KW}$H$Hv3ba-XOpl)oqzq?J^_}%K>s@|`9_`OxJ zLls|E_WoME;qAWJEk&D-j6Qu*!b!eT!!Heu?(YfjzuRW0=)7HjO7l(b)r8UJ2P?xY zp$#Qo2j+wiKWRMCqqtLROnEZH=KR$`1ig<3ww>2;#!g=F09%#IsoSdy=D06DCs~Yo%s$g6@*@*ed zY>`(HGS!c{`hplm?m$2H}=c|D;+WUy*M^Ka)L48AesK$!^1_J z215ZXlRw$_9{c;&CS1!~Yz%qs!8EZkc_qwbV)7i&)V_u!*6A5&`~)L57tk4O@BNlJS9M} z{B0o44OT!UOm*M~;##tAs^D0m#=H>VvkF)G*8^TraW^)*c2f=uVHK?a5nBb*G{+;| zOn{ol!rR0Oi0WIg)W0FlmLGsTmKcZ`RH)FK>W>V_G7E+1Cy-7GdKbLG9I0FbR0MWI zbFQb_mkS;d*OGuB`#VcvCX;CrmZeczm#;rhgeLQbomnPjaGH5BkiR_SlvTccgC`}Q zgAm#+WHMZb(m}r00q9sO;^fQ0p0;p5Vw-Dci*f%v>wbu-4X%JnBGQX#C zfi#wJyR)vfYMvHIKMrPMu1Ho~Oz*0!G1p7|L1$L#YLOp@Zv8 z`_bU_nQ&_HCOwyd20KY3XCm_#SlB_h_Es6Bo4=?ZIxqBG1**CXyS0O6TV?$68Rk?yNsL|Fp*{=lJeowjPNegT GQ2h(ld;zHd literal 1845 zcmah~eN!%UM#lbV3tk#;;9p8^Ti5Om=c z2AUt|AmGNK!rYMDaUx^E<~GygBomH_B0+67K1?!FLVDk=|Jym+Z}0E-ywC4>p51fy z#XB35=LUoZuvo0QDH2gCs1EqX{K4nhExHC!{PI(ig)H6mMGwFM%@?LfG4LwI6ea`L;TC8KPj{+jM_vizBo%;MRlNmu@xR2tTA98dguJ z^T$nt^RW8brRz1$gPxBYTo?VeJZ_tcXRV6FoAwJn4?_G_W2l?_pF_1%yFBOb+#NLs zlP^!TH-2My@Z@;E{X&f?L0>jHHq}xS?kRg_$aMYeG`l?;4khMaaTRr$&+Pl{tuAw% zxpddq-=DCqTxm7&di-p3V*vkc~U=fzWDA}hX*GHGPfj61sk)NJ9hWejK#R*c|fE?lm#nnV{}28K8fR4!0>k)1JFEwdSGQze@-&T;m`0t zGFAyO#dEgeeT;6Xno=Jo=*}E2riio=%jIn3B8z6`k4Jke7tqO7eA^tEQn1WQ(3NYd z1iJ4Dy5dZ91^hBx0UK6g#*#*=dHkeV$it%loL3a049sHg4aMLN(&kPdx1`aBb+SIsHSj^%{?E?Rnl-R4YX3y60a=$^zU@R3t+FcwYrxNbaBqCPO|54 z595xx(nSCYOpN%)RQJXWY)11UxpwzUfMq~p;IBS#MnJ|(KlZs>*t#<50+2OgYh?hB zI1||FB#Vv}GSx#d0TJpj1ymG(w(n=?g1Nx_Xw)!qw+DoBO0m#4(Qcs62g)86iO4nU z{Y8^frA(0JRw zFBbX&d%YHB0BrF?a(&>_Dj#?q+0t{^2j=ebjm}A+bIu$kaVQqXidp4H`5gzq&v{K8 zs{H_X2^LiNqVy9H+H7O_RD+fi~Bqo!?Miw{y&fQF^5hK+fsitBwU`sQ?<#c|6rb-Mv zjex9_UZSejW6gxlk&QKngil!ob6~|W2DG{TI@ye_tD!8vL{k%7fw)D#&E2E?tdWEHj-MvgBhm@CnC9M@w zr%~SCtpUAC6O44DQczIq;`6ul34L7gq$6WfI;X7|$oj6-M>UQeNMy)RM?CQ^E{xHlu^Bh0d xm>r9guRr^OU4UaZ){%nem8>un`QL+mw&mK<9jDj2bHQI9D@D9fq!VV9{|h_D2gU#Z diff --git a/third_party/golden/simple/linear_gradient_2.png b/third_party/golden/simple/linear_gradient_2.png index a2f1a692cc593205e3d3c40032a98ebdcd774351..f89163f154c389b42c4d0fbe27b7ecd98650a0f1 100644 GIT binary patch delta 435 zcmV;k0Zjht1^We%K}e-ZL_t(|obB8_ZW>V(hT(G~c3^sFT!WGYWChuSmtt3Gvmi@> z1z0jWaH>?eNqSP4IDm%FKk^t*o=380Fn8{`viue_t^$*>0wIy01tVUsU0<(O!{MQi z0mo;#tQri5Rg=k~j{?VMv8eiR=tICU6O+*aHGe=b=zG9yHmmu3-uD>(L!;5CE-o&5 zo$)S#eEWJ;)3Y9jw8w9cmxuedvu1s>wWjOY*Y5RpUB_jTKNz3;u+S-0oC-8r2z_RM+r^F49) zQw}=c9+#IlHJkPHH?_fMlaT>+lfVH5Y=Xgi4Egc9>guMa&0AHq)xY~%RkgOhUte3> zSo`;W&(F4=+qi#fudTIRd!;j^=eqVdrnC2bhHmru&#F4#zu=AZ9>{n+uF=QO^}X*w zZ(+6m;sl)6bUN*QO1r&XttOM+=fKHXEPMumNRz<v8H dpavIC-5>owG&VRgyT1Sc002ovPDHLkV1nDe>Gc2r delta 424 zcmV;Z0ayO}1?mNmK}wWKL_t(|obB8(ZWB=yhSB>XFCda@`YDj?9YC2f6?K-vQlOKpJ-`*?=Qs_z$hu>$<$W zoOQ;F1oHLE=jzU99MT@%x6#krKdkw6^Ki}h`6+v~y^SBS*CXb|`A<0e!FwHg_R+ct zcXvPP;^M>W52UK<;!V}3_cLwYTGd(GUEBD%J$RmaSEF?k@5b*Z-~C~Z^BsP^30GIQ zGyOpW?eiUx;U|;e0WOj77?a=u4P#*O5<~iJ)yHph?LJhss%pdTv9;ZEjjnt5ZM61@ zpZnWhzt_Cf8PexwJi{EnzX^T6t@V2H^|P5hkgn_M`}cQsJNKaHFpRF8tn>4?)pgzM zb6VdI!)i7A9C&p$8{a`75|gn3HVv@YZg>CQ1lV_ff9w;J!2%;20002MYxfgg^)#8~ SX*DeX0000)#T5!mGP?NG54) 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 literal 5166 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 GKm0%b-2ANo diff --git a/third_party/golden/simple/linear_gradient_percentage_bounding_translate.png b/third_party/golden/simple/linear_gradient_percentage_bounding_translate.png index 8d8489e0536758a7194b2707ab9e5c8848910a25..d1758ea3126d9e21b5588eebec8e83b6c0a572d8 100644 GIT binary patch delta 1821 zcmV+&2jcje5dII4L0YIuL_t(|obBD)ZW~n?hT+eMgI+=}ua_1|DW!$d4Xr{ELI_kL z5GZg3J&f(xNz=57x5Gg)_Shc(GoIaAGwXd0Xqs6WFVFmM?KB{IQ4~c2km@tn8vuMp zk+7De>aJ82$)z;tr54kP(-Cp^kJ<#Q*H z76>_xn5%0*Af6+RH5b={Ks-hqyPCcx1mY>;*ssZJLm(a^j%-a`BLeXZapc#;wIUFY z5Xa%_zGejC3F0WO&TB^?9w3hL>biym;uvv%RHu$>NgxgpNA;?{rUc>$anz^EYfB&w z5J&y0y2b?3Fyd%V71x?T8bln;D|^ieq#?xNPMK>@APpc6_ln*F0;w5s_@l_ZAdngn zhkp*eCj?Rx;_%lY_l7`fKpg(ddyfdDV#LuNdF~Z~RERj*C+nUONJWUFy{vmjAQd2g zj`rJk4+*3s;^>aFdr2TA5J&fH-%|o9h&Z|{d2c^=yOnk#j_x}-x%sshMN#B-EA2uY zVc{*-0f-|!1dfe;7s3N8@hz#)PPgg9`hU;-fy6cI!q z#DStZ9|&=vj7|qa94M=^fe;6((8)lquchN-*SkO$bTW`TccgpwZhi&I=wu+0boVZi zpuEloA`uD7>vSLzk)WK;2O<#(iVGqTiAYdPFo8%!g2M$Bh(shfOtAldkkeCt>FDU@ zhl)T?k`%=s#J_|ah(siz*f;ze$Ku~74=V6LBqC|MQp2y!(ce5CsV4%FL?phdd-!)A ztG7NUZ?U!zNwa(y{(cONACCwmO{kHCHvH*( z-8@bpdvq-lhClsy`Z*F`Payk$wIvdUKmB;t@TZ?+>o|efTt~w2rys9m__L0SKys-o z5{5thcvHi#tZUXIklYT9gyBy=?$hv_$K$;cNPcl7lWU3LZ~yS;SwkQPIz5%{f3ei$ zn&EHz@bBA4@^J{Hfc|Nu2ltnnOybWl{B0cmJbNXOg8KbP5AQEDnb>iEF#Kuf@MHM* zu1P)yffP6BM|$+-Z1qaQ@b5XE=NwyWni&2(YY3#IK|j*t2UATGZ?_nJdyOx{zj5w( z-PUy{kO~a@OFj8&s_EqR`wfP_?SF>j+{8*BajN64VL=;>+98jD~ZJL`#k*VYi`yNNKMWLOFe(|Nz)0#zkiM7!|-SClm8y1 z7NfyJFTeS;@k$~w{F`fT*Et;i>@~cC)MhkT=+)zo>u=mw|A;aCu7^Ll&$K;A1X8Q< zaG}?auQZK+n8@&_thrg|Wcc&!l|bq>9xinJ>w5lExXhjab>^u1=QA0{&V zE{8wsEv90GCR;%u&8pPg$qi5UJvA0y>J(c#bY zTnNOGi?g|Ydp_QOcqL)@cMsG#{OMmGC4WO8F1Gv1o0)M*|WB7O09Wwkm_DLX) zy&ui=_Qfdiw_7oWe`j6A!=Gob1mc0q(M)e&jx?VxB{BTFUtiDg+k3tJkU;!!IhyH@ zAI{d1F#P5|%k4Fm@_padIS9lfm!p~fd^Nm@gyAo^*I4#{@MoWcK)mx|G}B+N2b#~e z-fkr@{1pv<%09N25r~IAjA#1$bzk#Y`oEUK@MoPP-|%OjgFw7>HJ<99T(!p6cH>r&`33F#M}M zWu0U7dGil6mE;GzugV0{0w2$(`tQxD7PIBfF@`_yKKH*RwVv<)q3lrjR8L3000000 LNkvXXu0mjf$F^!s delta 1848 zcmWlZe>~Is9>*(-&DDPS5vO6BNuATVjzWu?HJrADaFm?ox8sx>EfvLlEsjk(SctP| z%8srS=OmnR;3$^zMs$I@zJ9M=%S-c z3B%{;S7{X=#>Os%gj#bKAsmW4ar+mGf8NUWfD?(PF~8j>63>6vA8qZN(YofD2LpWCxlX%#!a64X+;BUWW!G?doxtOxm1Twv* zsh=`;&8Ge|Sa<051i@X;Y z<*^+~5f;ITI?g9oSP%(lX1F8LX@w4l-InKz^A2IR{q`k`{PUMIeBNgcNT*IZoD?13 zsgzhDIHX56$ra^9LJ=&~2I89gkzlvWJyaKCcsW#TZ~`u1l8>en1w1hVKp50w7WqD) z@RtZkCkdd$P&$-3fa3F7O0FmZ6!bL;p7vLQYnB$xpXMC00M(P?Ih!bfU>0n#~lY%u;mu2i&s;BtgQS-M#XPs>_w{I z`%SGb{WTYe=g?h{YVf%k7vZ=AUy)#{L#py`iP&w6)~wz-Pw=*2?K_nKe1a;hzMc-3 z9FPPtZTV>4F<$JI&|@_GJ$%7(s11UXmPK|y9ZG^=Z@y6N3A6-lvw77S@gT8-P%vEr z60TX~N2gDbV8I7e{|>YPf$w?MnRmfoxDg8e`WM*x!7Q?%B?$yvR0~oM5crNK_NoH` zO9B#lg6&rS&(6``If5>`=f*Y-W8xL{LkbMNTd=;1{F8vlU%=M+NFdC;_(B^_Ne=l{ z{E@4$;B6}Sy9d%Ds=E(vu`7KaBF;#H5e`X9sB&PurZoThd#kaECrr=ydVDc$bT;S} z4R=oIC^zLf9DxO+S)x3uDZbz`rVA_KyKi$ro516?sGGX4pHTGbRACNSUz4DHvfR^P!?8G+x2aKy+I*%r{93nV}#dej~O^FnnRE?ry@grZYw>#_4?(Cn`&+a>cpA zE9xGlF9|EQmoMymo=bHf1eQi#t83$va=k=K;qclewr(Z>?>PBP`XY5EEL*=SH8b=M z9k$iax~bPN^mvaC{JD3O{(guWqun{rPxTKGd!_pK-Tf36{2(A*WRhCoHkqJ@#c0)< z^;(KiEM7iXeyt<$4)DX^Au!M@~G31^=9+ zKH)VsGnMwm(xrT*(9k5{ws#$Zi;TzmPI_w6cgjd=Ykh^o;NkTo)RG-6xKO-t;K;@b zRcdq)oXohmeZnrIIHD1_8ySW_Rqw6D?UOHtbD=4}aD95wuEM>SJ{HpU_U%CTpSP3^(b}>P1Pm`# zXX4%VR$nzx-5t197OVBM(T^Uf(d`<4#8yR+3OS<1=!bzKrUGqs6W|rRsHD4a{?^ntqgc>(KT$0|_=hVj5 zMTqn1*80D5p%uGpvez(dR)o4(KX$D_`LKWV6LGtKAyDXMurnCZRs;vPS1V3#0T07B Kz^9%Tb>sgTv3%M9 diff --git a/third_party/golden/simple/linear_gradient_percentage_user_space_translate.png b/third_party/golden/simple/linear_gradient_percentage_user_space_translate.png index 93891cbe084967bd5a4098cfd255d1fb83ee3a58..888342afae3ecdf3e71903ed3f26ad0acffeca1e 100644 GIT binary patch literal 2083 zcmdUwi&xUw7RMFwIZ5;@HI#_QPbO{16*{R|`3MBc%FNW%jB%=aC48V|YNq)}erly) zQ$s$w*Jwr)A5;ofqhde9$7pKT%1~3ZhniApx*9R>Z~lxqYn`+A{;a*vcb&b?Str+j zKg-g>*22KRz>>pe1R%Ek?`dX&tkoekWr#6M2w?db)b!vdkpP|G!wED)MylCy$iTp~ zo5S!9Oe&cfK5|a;1eY^rbN9G9ind+!Ldnsbey!23+#@JB#ap6^pIm0-E}`N?%5qaI zaKxG=WgBEk-tCe*?QP&%64ISPny~<{M#bIwquj}$4wqqIf<~>!nsL2|7YzTQ0he~` zd2-)%e>0S-I^`HEWm$daPC9Shd51;{cKw$EO6j*ol5ud_tY{fI^1`0Xip^#<-$FNW zQoeM|W!5+z^Tw+MeKv+m^GNFX&|_a0)Efy?SqCB}l9+AW%u(8yK>F(UGseFyy63J# z_jh?JH<)LPT8?p~ul^MqQ{|`I-1s-JL%?4*1k!RIofDxS>1Lau#nSg+;JEW#L+AWC zdshkx3kvin?sW);|6}WDCVkhOuo*yo3J zFTF_ZAn5_Tq9A#{kw$SAYUA}xn zLcHQuE3|0dq@GaDJ}ToY_$6R!pNXkdaCP{xjn(0_m|)PaQ0!4F%xh|2d_y_Xs4M}u zF@1>ki4m)jXH_OUUuLeF~?0Oe4b?^~g2?n-{E>}FCV;5J4pPMY2C7QWas zmq%E>|B{{btKxWS?(Vzex=!mV#unTE=Bx-3!sEL>itz33g-IV}?^s^#nxAbhmNRv9Ovu>CIiVf1)p-&}#w`7iB04$nUc zl+y6mjC(}>ob|Gy;Od{Buci0CjGSq|>)ETn6nz*+Yd!w3enq7z%BDTX{IF!yeai33 zT}{=F6y)&@_R~Sk^$&*$Q7dm0B5b?$wK1>!(5m-cEmvj^6DCKxeiyrC4Gq%q|2`P| zsdcw0?bd`}ysqsKsxkkBOK-V1eoL6I5r;3|)^N!r^tpz4%p|@QJ?MqEtmogC;0dI{ zAKUu;^Qjug*VuMjt;)YED9rExDn)qx#t@mXs-7SJ_M_EWm?*(-h}fmwiaJ6ftg=#g z+#hpCHG1#BJH(uA%f+MP_W>;7He#;V2zE6q&jZegUBl+Nh#wp!bhgjC z^aUG!x78bQhY73SXnoU6>9(6^zqloE?bD5L1-By#V(V8?JdGMJWo?VITR|Zx?WVKo zbM1>;AyN328+!9>w>Z-@v=3fMSu`SH_^KH%$S5q{6{~H*C~@ua4$Omygel^Vl$}0( zRd2>u4ST#Fy}+*fQK2J{Ro8}^6CiZh$MG5xFeLIkyGk^Q(LV@-&~~47`$+)5<>|w0 zb{#cchb60Q^-UfSS~1!~1lGp|vl*GcC@BGqOuIPOa3-kC@fh1qR#^=hyOMx#Ehgk5 zn~2&<0d(@u3KCE&pPD8Dv2yJ+8E}%nDkcKDy8dD^P+Qk|)*Bq*Uex8WAGJ)yWU))s zoiX|Bk|%d&Q6jf|t6?j$0H|u*%h2M3;$J|pgDlb-f^jl#5CogcBCbKw`H)808cwC0 zmrNA*N49+H@WOR!e2V=L{}}U0?}j#%bsm?z7#gy2va zM1$ZxvYdSoyj_+Z4Z)7G%*zmLE4xq)!4|0t(Z1ltapzbMvcvyY3@;FxirvY+LC8mM Nz+vuZ)c9~S{|_=CnXLc- literal 2144 zcmdUx{Xf(D8^<-D*c7&*vK+1L<0cg$jXGs^hD}l!ra2;Xj;)a#L`fg&*xYY!j)#~I z^F1Or(Q*^VP3}rj5{W4+mAT1X?m6qv_`V;H>$)D#>v}w{$Ln!jKU{C_IR{&1C5)1s zoSZV1LUxkHjvoeBkogjNsX!LC1v}Z2A%%tU=i_99U4(muyn^8jKG+IseuCoxUK-NO-t z9}3O=kPtYDs=;@SEp4Yf6Z&T5MGJN{3hiRQ3ZT#5xU(at}!4&{jJnot|)~~GTqt1T3@cm5vBwmAAFe%^o>ucA%_tM&o z7i$gi1T{@+?$&&`|7Qa<^wD)T^t6Z&q8Z%Tz}7LbdA~fcMS%nRI8|yteF&;YvD^6T z$t|)GW<!us6%kK$iAI;9kZx)D$Q zXc#2yG#~E$Bl*~H)RZfjPwS4F3*;l=X_GBQAA+ym__k;8VFFLE@wAKr2d_MHc+h4v z-x{ZOnBiMu(5yAP=;}?N5;t zg^qPTvm+Sp8Ps+rPM_&mqlPy2{!3sSr(g9Pk&ujDSn>ga$S#6 zRfIvz2o>`xcOP738~1CyxwgKTCD^QXd_UhEhd|#7TYEUV)vM%QtSj&~$}qNJMHTmf z`;px>$o9AH-*KAwlPiB8=Y5lR*52Db!tV+YN|q+peR2I*K}6NQgDYi>AdjVIZmfv8 zn6-ZJ0bTp}NzU6X0&Pn(8bx|BQF4T&MOpOz%m z_piT7b2nLCF8;0HXG@4i<^&~#EbTS1iCFNP<&|G_k%>#mnKJ7Y2dZz@*(2K*lYDa6 zu@)8q7)2+EY=W_<_Si1fiV*3@?pE1GlWGffCZ?Acb-g^hRI~VT+}lL0-eSL0`P2|q zjGfNO^H)G%G}H6&rK|S$!``JC+o)bBF`BekF690aA)mhI zHmTa2+Bw=1k>Jkxfj{O@5$)1`L5R)c|7>Vsiz zmW$`9h?-JGqj^RZ{h?iNnO^O?vS2Gg{^lU1ZBOJv|Bb%GumjWv!IvA!A|@)rcHqQx zxJhZjeykk<6~G!xW(kk z3xF{T1e{W4CB)g)_JLZn(=xhs6YscHZuq@uZh^(~O>iX$hNV)tZ<4Fn{)Oiwo4iZxgRt2@gD^$wlgdbZ7Gl%ziwzf45w(w=?r(qp{weTAq>SC@B%DAw^|$ z)9iN%X3PrLJJE=%s`>hk7-I_(3G0kYI)ds@?=g48=%Lv_Y;xAn{zSFJJmI9zJ6t)GjSpEqfd8 zrE87d!~|Yne?j`U;c=^f*LRZn8Gmts;CTX)OF2SlkmqrL;91KbPa46X!v zZ^xk!(>irT5ZBb(ypxPW+v^PdfShI(8PHK2GMLFBwsC+eY>Jcv5Re^b$k8mg+n>Ajus{9T^*rL(d>7!EeR4p|nIwwhh)0 zi~bG8Iml_D0;6bLkP1}&CncMNHN@Cfv~)Tj^W5f!;;JoAKe-%|PO)nX8xA2m6>Z4} Y?RXrTT<_)~`z6RxtsTgvB(LcI09(trE&u=k diff --git a/third_party/golden/simple/male.png b/third_party/golden/simple/male.png index 6b5c887f53eaaf0290cf061c1b97e5c50d993aea..046776904bb53d9c587f23b630e394bd87edb679 100644 GIT binary patch literal 4057 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 diff --git a/third_party/golden/simple/nested_group.png b/third_party/golden/simple/nested_group.png index 7f626d0d0ad4314ddbd3156f828bfc4951cd3c2d..a99844327c1bfac8f198f09e248975e2ffc2e37a 100644 GIT binary patch literal 4013 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 literal 4683 zcmdT|_ct6`*B-;gVD#R*C|AAFq6J~}5-nN?B6=CUcLovBOOz|h6(vLog6M+G=tdnP zx-pF2eRIFx-XGpS;5}=dz1LprIcuMN&RKgu`@jtKHNhmzBme*atOZdw#_1pbPGUlw zth1;u#wk3gv8F1Z9>KbcGYFunS|-G}5k~Bo1OQN-X{kRo3Horb;*rW4Xg`cSM4-_q z%mF6&g8kfmwfNx4lJk=R*a5*buOUQ*(}d0xq&@SA+L%v0-crbrZ-ya!y1VRv)R2#W z+KVK~cq+z(4x$4|*0x^11PaP24+M5=uAcNOEi1thx-Zdk7Dkd$ffoVc_u=J}kwpwp zC?evnWFfx@6jZ#;#qBlr=7KQEPx24$b+zcEOG8d>CEBDUivMvl<^UDdg$QtWwFNIV zHnOoGp*}u7)>Zc*&OX*e!%$)ZAR{9q9{#kr1aPP@#U(EfFSC@2_YFZK8R=N_;+-(Y zg=B-gtypJ7)TlWn%k`}B4TB(ZbUuLmTPMuJ%cy3nv=!Xahp-^{N>&f{JUh??^aFWL z$sHI7K2o9+?8stP2-H9#ZX9Oj)MMHcbZBnZXD~}6?p{cEGdCmNf%t7Juy{N80F|U~ zTAw{)eoTv24X>qtMDJyc82@FOQ`$_Hon7RUuM(VHYBfj_MfcCcK6Jl@4v=!KR7VAn zYB*V}dG{Ki+d~?)A5ALzk3p1jkFwSE&^2OHLxvLp5bS@cSPjdW(izcF;=~EPIL`m_a@!t8!&yA4JEGYyr;`VidEtcnmcdL z-(&Qflv_)@#g{R9D7sMj^svX{#`ds^TUM(Y275Q4FO9md`OX>1X+gRqXQc!3tEsnr zf4o1@Tq@({B}^uE0r@}~izSO)i5=+226(xSq1#nPTO>)Z{&?NgL@OPEx6c5oeaUOu zslRv%DI{6fr?a*Qup0q2FexS@Z^Tc#3xoFX5~$T2sq+Tu?rT6t|uMvVZ&`)x6Z)OI*dK%C1-K?+tl5RM$Yp5vN|ErpGdp8$Aai5_`4L8 zY?n3~H-|i#KbHNQMr~*y6=uJN=D?NaLygW4*%Rv&a*U5MK&tO5lhc|v`#yk4ZE0_M zG>O?F3e>`@n6%O;CDjg4ovV;xBIAGP^Oo}*Bd&m$pMgnrcX3or8bec}Gb?>qJ5=bhJoK?#?6NbjjK)DT7BN;FFXtsUeQ;h`857y?ELonO>hby z5vl>)nz0RXEOwMV;nF`X+L>pn_zm>2P8@-2@iV+E3;4~#Yi_&NovveSj}~Mh*EIo4 z6R``(UV}6OUuWq*(b&zyJyi#3nX%al9h1s?*yZ|#oc%(9#CaPZktni{mOL!Ao@d-U zY)zzJv7Zh4LPwJz6NFlGT*Hlcy>Cz=c<33&L zh69r%b?N~gI8mtgvfW<%NrC0>?(z07e$GWKlp1ObkA(^S^m}Xf;aVq+La}#pX0jE* z??GCw|lQO-vD2E#8l@WX69X5AsFSTh19|} ztQiAoHVp3RcoHMuJrA!6@XvKa0;}asZQHL%_N5+%qDRDhhd#N?rLQKD-gYuO+MkZ^ zDBjXium!zAA_~#koVdJ^%V1l1J7msebxl6($3xzZk92R7zx3fARvNjA-45JrE8mRX z5R!|KzfcY`?;coyZ~NJ*G5aN&^IMU60|5Lj=_$Vp5d`HRXdt zB0F98PG&L@BR}VKr;)2OD%t@s*enuca}T6oiho^ixxrQ>MQV}z5DjZV3NBPs)_<#x z)~(fB(~ZnbM7zcL(;Eh8%||uO3eR|k#lmJ`IDm`SZ`GC_c(x9@jLT@#u3Hgh04=tE)S%G>iFnM zEiHY)m+pkssd(4u^~Hy&!^ej`ka8+~lyv+osonzIRW^OIPtrYAs?@EnT4XY9YSrcSWdXKMnFUsEZxq2@Egr*!p_z!zgNEfX zRlFY5K)^x5+_WL5Mh}2Ted*9f=vbdQ3@S|vk!2(l)-sKUBv!XYWxHS2w1LMtdm$Xz z3DQr?uY{uLcD*k7p(VF)>qqEX1Lt680Co0AGJk?}tjp zQQn-5hN<;4__fSMcg@D_fwcsouyS_yQ8tD`U-C||Db0vA(3gT|_ZGqZqos z1k?L($kn#A>O17CL=XH2K~J}|$j?|^|GgZDWJY=9s!tA)QrQdjMgILB?Q0$~-r;%V z?4^Lk#K5*N~zj+mxK zX!HsdOGg6DIwRL2ViHSUD}?AHok!}c+r-%wb&igvmrJ_8SMPheavBMb-r-kOr{2l^ z*1zEZid`h==%C`i*N;u>}+LxZ>K8H6>S{${^foLcwh4&OLuiQ zM}fbC&)^UT2gGYfkHxe2eOA!1L`rItiahalIubPQ=lJb+?WYr=p#ziv5*{*zP$-|V z+E#mqwnG=P*#YJewSvr#|1I5!kE+?=LW{&ZT}I#pR?XT~|0 z_XMI-tP}JtM_GWa)I=ED)K0n~aG&;Tmcw^Z^*tTv%NBh->{Ky!a%4)#X~i z%*)vvi05scm?9(gCFE|uyz={KzgbX=(+N$v*+^IO$oqOi-!bceG~||T zPuKZ7)=}GyZpyp@y$$Kd6#SpWGi6gG&KVSfc6`W(C@|Ln&3u$mIKpzdF5ABA4ATvN z+tf=f2*r3M(q&ZD!8v z%+T!Ly>Z~_mBT&-tXvvLSn9{>j~*+Pt%SZhlcJK{K`?m!AyxjpyaPsvsb|(0@HlkTS8MOm(O|*buFSPT z?ucM+Qu)`LYgV3-_c=C_zE$#~=~kcgvupOv^YbIAypDy-k3UPf_Li!)*Ze6b?$WPu ziGW6(_lW-sk#Y9(pivHp@%e~F$sq-qHa zocG*FBq$>cukF+L-$`%IDb&qiaqDm-qtQQhclM>7*zJ>F@eganR;=VP6$V}M#l-*N}%)UO?G!1h5LkAgPo*4tDz->&BAj7#N3W^+wftWG?( zJ=h9v*z4r8=jFS5lS-C4sn|-R_tvY;@>30t32g=nKkQl*6S1(1EHpU!Jx7Oa6znG<|b z@^g_UdRf#8A(>m~5aC7=dSW`?7S|F1YYxwB2DvWgTF=~UP)2D7QPqloRNbR@t~j|qA_@c9Yi~CPf;!348J3a!5ekS0a&=j9Epq% z6v-LN=ABgy0PCTT zn8#x~t&|%O9qDJfU*7k(!6YCb;s!vq7_N->yw&xz)sSRI-UT1$_P~BcrXNcqroOeg zb0gW%jhf)&Y>}1&rXL2X_9RW>&&p(<4g5(-*a19CoK3|4+J#BKFc^$aHjhkq3f}e) z-X7=U(Qgf9rTyNoWoCTvy+>$t2*5M|b&DSGb_2y7bzF0ONPsZ+;ZthS z5K~OijZ?m5=cG@jq8Ns~IBT5LdR1VL{dKJK3usq z+rY-M)aawgz`!u9qd_^=a6ZtU zpkJw?9`*)7hy5F;A5l_qkf;wN0;&Gj&EW@pBMiYi)h7jsxDO$K)-!$edR4oa{{uy0 B@qz#V diff --git a/third_party/golden/simple/opacity_on_path.png b/third_party/golden/simple/opacity_on_path.png index 3c73a53c114b3097929879b5a341c273cfbb70e4..694216ddeed7c0c9fb955b806ba13be53a230170 100644 GIT binary patch literal 1443 zcmeAS@N?(olHy`uVBq!ia0vp^CqS5k4M?tyST_$yF%}28J29*~C-V}>VJUX<4B-HR z8jh3>1_oANPZ!6KiaBrZ>K03fOSC;SpR3c+$RzWCp;=X@Q^sVIbc@ zMS)2$puuW#ldSLTu*y$?H`7Z?VvU`)Z9Q&WoqfJ8<9l4~vE%*n^($9Rpa0vk&;MJ2SCC<$g;+P+$vnns|n8m;Mzjeey z^Y4Yo%7)rj29;J>eHuh zTR!H${wneCtnbyIKP65d;e0aT?wy|bZ_0D`%1yVPA8uQ3=XX%;RN_77Epg$0zeUfs z_?NkJP1V;||KGpAqtqxf>+7ypUthmmGi7$f^Uv3mZ=Mo)Jwa#s<5NG@w&%P*^z*_Q%PK8bdax96tXua@xv!VAH(X)w z?DOhhJO6~5T|W4A*H;ggOIy$WY^&W8)Au}6O4#H4x^-$FHUHdQw|=&Kh=9lXu+@KO zN97jR-Yxma^fL6ZXmJux+|q^?TdReN!B&Os2kG zQ5IbmNPIKB>ibMK_* zp+nWx(_u>rUogGAdGu)A{78HI{C_MljbCykj(L2$2sHk2|5|s&3Ge34dv`x1TVmBb z+icseRYE5cckIY0nt7~z_Js=8B969&ua0(~TvKxK^76^I9&tVi$XTWvypQMUqokn1 z5Y8tX&ZLFv$NLp~fBKSn^=9Pjz(4H{d}q^kU43zD*?)<)RnO0>Z-072;Dq9>HB;8| zGoDWiwf}1}H)8va`&A4kC1qyo=1iYnULActQNo|eufXeTJ}@D=yFZ?iy>Ug==VxWk zl5HQo9&g^f*YdEwfZOro_3cLU-+xnFz%SPmIA`8FUkPcZhr!2>KYslvspieiBtyHc zuMW4rubzLre|hDVH`<&nZ`&STJ{=Oa+HlhM_xAsJCbjb)-~al>F+rw>uVrL=*Y}0} oTmR5NA3f3rU#UP|LG_1~+xO?X91gKEU_r~^>FVdQ&MBb@04^z1pa1{> literal 1710 zcmd^Ai&N4E9A`xOOIKoY*HX_&PKL1UUa5t=eZFf2(sJtI$@6{V6zKTDIwZhysY-}`)D_xaxUzW2TF-M8#mWcX$q zM;izPvYCL#ku84c9|f!|wk=*Fu(+>s$l)On$%wPTlE8982+@E=SU_4S1Y#9W!2J+? zzIIW+7V(7XtXk&hcx#8@K5iA{JLgcY(7iz9g--_%xZHyqixAZf(TUI7dNX_8E3Mzu zRw{^ka59h?m;y^Eoc<-?)6&{{VP{q)7`3O`TxC)f23c=?7e}EysgoCS#UMI3U?=Pj+|dg^o=653}c;$i%@_1D~7TSuDj#aE@DR?ZFBiXS99I)5!4+YV)S zw4>xq4^kx2$!UIFFB{cr33YY4i5kqe$DY%o;cQILK&atUj$xRu$)eIojL-3!m!b&1 zP$1A`y)OlX6>^4~yfA5fQPPTEF_r|V$6ID_RZt(R>J;v^+MAm$s1wzg7_Ne4EDH$Dyz_vQF)X^5|KIm8WQl?JGf z0>UVSjZRsjdy&3C06W`J0R@gD=f>gC448;#dKGn^88b{2(XUa@eg~qb?eVCZnx@H> zk3o}@n>^rVd99l(l%W6IYXWHtySJpDJj?(+K?Dy#)260$(-%~NS-NE_JpK@XKIPyr zpNu7we3FYpEA8#^%}<{S#o`HyGpQaf0mE@fG2{JYE$l*9AFE7DoA2{2?P=I zQkl+wE0i#5%5`LxCs8P)0y_)Kz=E*(m|ZwoegZPruf7?wEMX* zP?Nq1?d#jY5w~`BHnfJgbH_Y=RD#>tu7~`f1ocSdqW5VZYY^$rOI$-n|85U((DU*V z#QYU3TbRZ?2*RpkJYx$gVLaa0hO)Px0koS|EA?n<1s;_LlX(oJy&{EU2_Dm|L7b(D zB$z}k;x>+P2KnK`65>?V)K?k!R_7~HyicS++Z@sf0wWCfS`e8WhFdP%iqHmHnowk zd3!9o$yqwlL2|%1yDFMAum3Eg=Rd;(=orhD8J?BL zyqk4k^>|AXOb28iFuc&Ne(W6@D#c(B%qvFA0d;gm_?;O8vp?3?(^Kn<;dqq#rD&?F zktLbs4-N|V#-$!zc7SGJXtbR?vw5Nt=H)eWk(G-9(M(rvSe2GIH@BQzwZ5*aJ2)Eq z+RVW!u3SbrIoYI5pNQ-^FZGs~9Po|9FO_|3{UP0rnQlfOp8E2J<^I#WK4bd%)b%<#(vFQ+WM4Tr)e{m#R)z z8ehG!Rc%+5$DMg@gMu%3@oleeEGbdu&w6_mWtAr<+bw6FDGuN7WTsK66O`P%BC2;8 uE9GkNTdG$3WBKEY{#x5_V9@^~zCb8-=)B6}F{0(?KnS6cI7vv#rN03r4!I=& diff --git a/third_party/golden/simple/radial_gradient.png b/third_party/golden/simple/radial_gradient.png index 68361b211ef40b6a496d5665a053c6695bddb21a..10f672dd09f0520371c9463762fde4ae8c3c5ea1 100644 GIT binary patch delta 2958 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 Ef;tD?hX4Qo literal 3286 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 Z|NhM0=eL6lkJWuk48Z+ibzUc_{|CnZ3EThx diff --git a/third_party/golden/simple/radial_gradient_absolute_user_space_translate.png b/third_party/golden/simple/radial_gradient_absolute_user_space_translate.png index 5c564d088e0b66bed4becb052b8742603821facd..58976fa5bc3b1e6432c1c037ab27b7d19d546892 100644 GIT binary patch literal 13507 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 delta 11807 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 N002ovPDHLkV1m#eD#ri- diff --git a/third_party/golden/simple/radial_gradient_percentage_bounding_translate.png b/third_party/golden/simple/radial_gradient_percentage_bounding_translate.png index de39cf7f3c56c12518dfa51947eb0755ada9dcfb..d954b9d44a82bea4b1c44135d80cdb2794c5b615 100644 GIT binary patch literal 7056 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 HYux_<=Dtp4 literal 8338 zcmeHNXEYqZx8G>1x7CTVdheaE>aI@o5gP9WEmrz2NH~@eh0Mme&1{dwwVRJTwQb>)jZoP}1 zz4@q1m}&Y(Qn4u;o#0>n!Z~!*oHC=^($sA7nN$kH-LmYDXV)%L5T<030`}xVeEl@7 z^(Y?bCtnDtY!dmAXzH2m4?K4%k!Mj-O!WUh?f*a_hbsR$go^`5164C|+8~VP7=lnUNjBj&>=3M&y zI0I;y-Te(`W=oQfl+PwS<{J9t9dj5`*`N1RHqfk}F_N6eAuA_aTPY}=GV9Q$Yi8k4b6 z|2s&(vC#wWPw7VI9w$a@hX-I6FgjYFZGh0!$ir_V9I6p*>S8=%K(UX(-!%((P@=%h z^;4rX*=k2!2hlnaQ@#NhBv4i`tE|!aPr?s!Dt?!v0C8OV(@Y`t3?ua=D%S>m4Zvi% zz?q^WK;l7g2Zw&zGAXY%-#af~V7fE4d~rkE`&6ftakeaq3BbomEkJ*oE<{Q$zJMrwN;?;xloG^&%72 zYG^ltoTzZom}HjMo7FBYtT9y^KXAoO_;aj6c6(ha8HLINQiO`jkADzYB->J$RJw?f z`!~Zk>#-s@^}QG214Y|@@>Wl3*}Ew6YfJOiHBzkBlRtS-8rwcB?w1?lRt;#7JCm#3 z^Wl_P%J&=)nL6X8bF(C~C=B@K+8Pt(&mfNa9o1@UkTXeq+`i&r6t(vzlBKSS(aoVs zi(A)>7J>DkW)!k?*spqGIM<7{Ky``>i&4z#2#eLZFmf?%5PlqU0K8m2N^yYfi{rFqK zXvSg`qLUn)nBdw}#8--yqnKI@@R#Pu^>mOXws&5{Btoa~F1c4&{R~$_U z4}tg9sKhOWqvTXMj2GDWpcASqNw2n)&&z?U)=ie3;~Mefs_pg`nH*02MTl(PK$=;otPs z7>M0N#a1!#YF2Q#U|yq_iOb$)6gMlp)2*S1OFxYwc3-QDY9*^SL_5WD2xeRy8RA