diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..3ca6856c2 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +# LFS settings +# If changing, also change in .github/workflows/ci.yml +masonry/src/widget/screenshots/*.png filter=lfs diff=lfs merge=lfs -text diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0c94e05de..32bec6480 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -57,6 +57,12 @@ name: CI on: pull_request: merge_group: + # We run on push, even though the commit is the same as when we ran in merge_group. + # This allows the cache to be primed. + # See https://github.com/orgs/community/discussions/66430 + push: + branches: + - main jobs: fmt: @@ -102,6 +108,8 @@ jobs: - name: restore cache uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} - name: install stable toolchain uses: dtolnay/rust-toolchain@master @@ -137,6 +145,8 @@ jobs: - name: restore cache uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} - name: install stable toolchain uses: dtolnay/rust-toolchain@master @@ -161,17 +171,65 @@ jobs: - name: cargo clippy (release) run: cargo clippy --release --workspace ${{ env.NO_WASM_PKGS }} --locked --target wasm32-unknown-unknown --all-targets -- -D warnings + prime-lfs-cache: + name: Prime LFS Cache + runs-on: ubuntu-latest + continue-on-error: true + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Cache git lfs + id: lfs-cache + uses: actions/cache@v4 + with: + path: .git/lfs + # The files stored in git lfs are all in this folder + key: masonry-lfs-${{ hashFiles('masonry/src/widget/screenshots/*.png') }} + restore-keys: masonry-lfs- + enableCrossOsArchive: true + + - name: Fetch lfs data + if: ${{ steps.lfs-cache.outputs.cache-hit != 'true' }} + run: git lfs fetch + test-stable: name: cargo test + needs: prime-lfs-cache runs-on: ${{ matrix.os }} strategy: + fail-fast: false matrix: os: [windows-latest, macos-latest, ubuntu-latest] + include: + - os: windows-latest + # TODO: It should be possible to get WARP working here + skip_gpu: '1' + - os: macos-latest + skip_gpu: '' + - os: ubuntu-latest + skip_gpu: '' steps: - uses: actions/checkout@v4 + # We intentionally do not use lfs: true here, instead using the caching method to save LFS bandwidth. - name: restore cache uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} + + - name: Restore lfs cache + id: lfs-cache + uses: actions/cache/restore@v4 + with: + path: .git/lfs + # The files stored in git lfs are all in this folder + key: masonry-lfs-${{ hashFiles('masonry/src/widget/screenshots/*.png') }} + enableCrossOsArchive: true + + - name: Checkout LFS files + run: git lfs checkout + continue-on-error: true - name: install stable toolchain uses: dtolnay/rust-toolchain@master @@ -192,8 +250,21 @@ jobs: sudo apt-get update sudo apt install -y xvfb libegl1-mesa libgl1-mesa-dri libxcb-xfixes0-dev mesa-vulkan-drivers + - name: Install cargo-nextest + uses: taiki-e/install-action@v2 + with: + tool: cargo-nextest + - name: cargo test - run: cargo test --workspace --locked --all-features + run: cargo nextest run --workspace --locked --all-features + env: + SKIP_RENDER_TESTS: ${{ matrix.skip_gpu }} + + - uses: actions/upload-artifact@v4 + if: failure() + with: + name: masonry-snapshot-tests-${{ matrix.os }} + path: masonry/src/widget/screenshots/ test-stable-wasm: name: cargo test (wasm32) @@ -203,6 +274,8 @@ jobs: - name: restore cache uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} - name: install stable toolchain uses: dtolnay/rust-toolchain@master @@ -222,6 +295,8 @@ jobs: - name: restore cache uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} - name: install stable toolchain uses: dtolnay/rust-toolchain@master @@ -249,6 +324,8 @@ jobs: - name: restore cache uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} - name: install msrv toolchain uses: dtolnay/rust-toolchain@master @@ -275,6 +352,8 @@ jobs: - name: restore cache uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} - name: install msrv toolchain uses: dtolnay/rust-toolchain@master @@ -300,6 +379,8 @@ jobs: - name: restore cache uses: Swatinem/rust-cache@v2 + with: + save-if: ${{ github.event_name != 'merge_group' }} - name: install nightly toolchain uses: dtolnay/rust-toolchain@nightly diff --git a/Cargo.lock b/Cargo.lock index 7c47cdd21..645f0aa4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -535,9 +535,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.16.1" +version = "1.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b236fc92302c97ed75b38da1f4917b5cdda4984745740f153a5d3059e48d725e" +checksum = "102087e286b4677862ea56cf8fc58bb2cdfa8725c40ffb80fe3a008eb7f2fc83" dependencies = [ "bytemuck_derive", ] @@ -567,9 +567,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.6.1" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "calloop" @@ -599,9 +599,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.6" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc" dependencies = [ "jobserver", "libc", @@ -1078,9 +1078,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.30" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" dependencies = [ "crc32fast", "miniz_oxide", @@ -1107,6 +1107,15 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "font-types" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0189ccb084f77c5523e08288d418cbaa09c451a08515678a0aa265df9a8b60" +dependencies = [ + "bytemuck", +] + [[package]] name = "fontconfig-cache-parser" version = "0.2.0" @@ -1133,7 +1142,7 @@ dependencies = [ "memmap2", "peniko", "roxmltree", - "skrifa", + "skrifa 0.19.3", "smallvec", "winapi", "wio", @@ -1595,9 +1604,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.2.6" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" dependencies = [ "equivalent", "hashbrown", @@ -1821,6 +1830,7 @@ dependencies = [ "image", "insta", "kurbo", + "nv-flip", "once_cell", "parley", "pollster", @@ -2015,18 +2025,18 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro-crate 3.1.0", "proc-macro2", @@ -2034,6 +2044,24 @@ dependencies = [ "syn 2.0.72", ] +[[package]] +name = "nv-flip" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec3c68ac226790270de1d9d0eb5853832d82a34b62199ab2a1a4756df1a1974" +dependencies = [ + "nv-flip-sys", +] + +[[package]] +name = "nv-flip-sys" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "932e1eed40002ba70fccac6dab3b64be3301607c3ee88bd14989c4d4e1c1c993" +dependencies = [ + "cc", +] + [[package]] name = "objc" version = "0.2.7" @@ -2332,7 +2360,7 @@ checksum = "be05c1c99b0bd9272eb75f495d47090add32275015f428aefa370b41179379c3" dependencies = [ "fontique", "peniko", - "skrifa", + "skrifa 0.19.3", "swash", ] @@ -2465,9 +2493,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "presser" @@ -2576,7 +2607,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8b8af39d1f23869711ad4cea5e7835a20daa987f80232f7f2a2374d648ca64d" dependencies = [ "bytemuck", - "font-types", + "font-types 0.5.5", +] + +[[package]] +name = "read-fonts" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c141b9980e1150201b2a3a32879001c8f975fe313ec3df5471a9b5c79a880cd" +dependencies = [ + "bytemuck", + "font-types 0.6.0", ] [[package]] @@ -2599,9 +2640,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.5" +version = "1.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" dependencies = [ "aho-corasick", "memchr", @@ -2754,11 +2795,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -2822,7 +2864,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ab45fb68b53576a43d4fc0e9ec8ea64e29a4d2cc7f44506964cb75f288222e9" dependencies = [ "bytemuck", - "read-fonts", + "read-fonts 0.19.3", +] + +[[package]] +name = "skrifa" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abea4738067b1e628c6ce28b2c216c19e9ea95715cdb332680e821c3bec2ef23" +dependencies = [ + "bytemuck", + "read-fonts 0.20.0", ] [[package]] @@ -2938,11 +2990,11 @@ dependencies = [ [[package]] name = "swash" -version = "0.1.17" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d7773d67fe3373048cf840bfcc54ec3207cfc1e95c526b287ef2eb5eff9faf6" +checksum = "93cdc334a50fcc2aa3f04761af3b28196280a6aaadb1ef11215c478ae32615ac" dependencies = [ - "skrifa", + "skrifa 0.20.0", "yazi", "zeno", ] @@ -2982,12 +3034,13 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "b8fcd239983515c23a32fb82099f97d0b11b8c72f654ed659363a95c3dad7a53" dependencies = [ "cfg-if", "fastrand 2.1.0", + "once_cell", "rustix 0.38.34", "windows-sys 0.52.0", ] @@ -3113,9 +3166,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.39.1" +version = "1.39.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" +checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" dependencies = [ "backtrace", "pin-project-lite", @@ -3123,9 +3176,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fb9f64314842840f1d940ac544da178732128f1c78c21772e876579e0da1db" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" @@ -3286,7 +3339,7 @@ dependencies = [ "log", "peniko", "raw-window-handle", - "skrifa", + "skrifa 0.19.3", "static_assertions", "thiserror", "vello_encoding", @@ -3303,7 +3356,7 @@ dependencies = [ "bytemuck", "guillotiere", "peniko", - "skrifa", + "skrifa 0.19.3", "smallvec", ] @@ -3675,11 +3728,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3787,6 +3840,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.42.2" @@ -4262,6 +4324,7 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] diff --git a/Cargo.toml b/Cargo.toml index 3bee915d1..8c2c7a64f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -119,3 +119,4 @@ web-time = "1.1.0" bitflags = "2.6.0" accesskit = "0.16.0" accesskit_winit = "0.22.0" +nv-flip = "0.1.2" diff --git a/masonry/Cargo.toml b/masonry/Cargo.toml index ac30a92da..bb7756649 100644 --- a/masonry/Cargo.toml +++ b/masonry/Cargo.toml @@ -43,6 +43,7 @@ accesskit_winit.workspace = true time = { version = "0.3.36", features = ["macros", "formatting"] } cursor-icon = "1.1.0" dpi.workspace = true +nv-flip.workspace = true [target.'cfg(target_arch = "wasm32")'.dependencies] web-time.workspace = true diff --git a/masonry/resources/fonts/roboto/LICENSE.txt b/masonry/resources/fonts/roboto/LICENSE.txt new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/masonry/resources/fonts/roboto/LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/masonry/resources/fonts/roboto/README.md b/masonry/resources/fonts/roboto/README.md new file mode 100644 index 000000000..d7c8b79f6 --- /dev/null +++ b/masonry/resources/fonts/roboto/README.md @@ -0,0 +1,3 @@ +Roboto-Regular.ttf: Copyright 2011 Google Inc. All Rights Reserved. + +Used under the Apache 2.0 license, which can be found in [LICENSE.txt](./LICENSE.txt) diff --git a/masonry/resources/fonts/roboto/Roboto-Regular.ttf b/masonry/resources/fonts/roboto/Roboto-Regular.ttf new file mode 100644 index 000000000..3d6861b42 Binary files /dev/null and b/masonry/resources/fonts/roboto/Roboto-Regular.ttf differ diff --git a/masonry/src/event_loop_runner.rs b/masonry/src/event_loop_runner.rs index 04b55ae70..e9bd92717 100644 --- a/masonry/src/event_loop_runner.rs +++ b/masonry/src/event_loop_runner.rs @@ -224,7 +224,14 @@ impl MasonryState<'_> { MasonryState { render_cx, - render_root: RenderRoot::new(root_widget, WindowSizePolicy::User, scale_factor), + render_root: RenderRoot::new( + root_widget, + render_root::RenderRootOptions { + use_system_fonts: true, + size_policy: WindowSizePolicy::User, + scale_factor, + }, + ), renderer: None, pointer_state: PointerState::empty(), proxy: event_loop.create_proxy(), diff --git a/masonry/src/render_root.rs b/masonry/src/render_root.rs index 8c0f52b95..cd5d2bee9 100644 --- a/masonry/src/render_root.rs +++ b/masonry/src/render_root.rs @@ -5,6 +5,7 @@ use std::collections::VecDeque; use accesskit::{ActionRequest, NodeBuilder, Tree, TreeUpdate}; use kurbo::Affine; +use parley::fontique::{self, Collection, CollectionOptions}; use parley::{FontContext, LayoutContext}; use tracing::{debug, info_span, warn}; use vello::peniko::{Color, Fill}; @@ -75,6 +76,12 @@ pub enum WindowSizePolicy { User, } +pub struct RenderRootOptions { + pub use_system_fonts: bool, + pub size_policy: WindowSizePolicy, + pub scale_factor: f64, +} + // TODO - Handle custom cursors? // TODO - handling timers // TODO - Text fields @@ -93,7 +100,14 @@ pub enum RenderRootSignal { } impl RenderRoot { - pub fn new(root_widget: impl Widget, size_policy: WindowSizePolicy, scale_factor: f64) -> Self { + pub fn new( + root_widget: impl Widget, + RenderRootOptions { + use_system_fonts, + size_policy, + scale_factor, + }: RenderRootOptions, + ) -> Self { let mut root = RenderRoot { root: WidgetPod::new(root_widget).boxed(), size_policy, @@ -107,7 +121,13 @@ impl RenderRoot { signal_queue: VecDeque::new(), focused_widget: None, next_focused_widget: None, - font_context: FontContext::default(), + font_context: FontContext { + collection: Collection::new(CollectionOptions { + system_fonts: use_system_fonts, + ..Default::default() + }), + source_cache: Default::default(), + }, text_layout_context: LayoutContext::new(), }, widget_arena: WidgetArena { @@ -192,6 +212,23 @@ impl RenderRoot { self.root_on_text_event(event) } + /// Add a font from its raw data for use in tests. + /// + /// We expect to develop a much more fully-featured font API in the future, but + /// this is necessaary for our testing of Masonry. + pub fn add_test_font( + &mut self, + data: Vec, + ) -> Vec<(fontique::FamilyId, Vec)> { + let families = self.state.font_context.collection.register_fonts(data); + // TODO: This code doesn't *seem* reasonable + self.state + .font_context + .collection + .append_fallbacks(*b"Latn", families.iter().map(|(family, _)| *family)); + families + } + pub fn redraw(&mut self) -> (Scene, TreeUpdate) { // TODO - Xilem's reconciliation logic will have to be called // by the function that calls this diff --git a/masonry/src/testing/harness.rs b/masonry/src/testing/harness.rs index 250948301..a2cf930d7 100644 --- a/masonry/src/testing/harness.rs +++ b/masonry/src/testing/harness.rs @@ -5,7 +5,7 @@ use std::num::NonZeroUsize; -use image::{ImageReader, Rgba, RgbaImage}; +use image::{DynamicImage, ImageReader, Rgba, RgbaImage}; use vello::util::RenderContext; use vello::{block_on_wgpu, RendererOptions}; use wgpu::{ @@ -19,7 +19,7 @@ use super::snapshot_utils::get_cargo_workspace; use crate::action::Action; use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize}; use crate::event::{PointerButton, PointerEvent, PointerState, TextEvent, WindowEvent}; -use crate::render_root::{RenderRoot, RenderRootSignal, WindowSizePolicy}; +use crate::render_root::{RenderRoot, RenderRootOptions, RenderRootSignal, WindowSizePolicy}; use crate::tracing_backend::try_init_tracing; use crate::widget::{WidgetMut, WidgetRef}; use crate::{Color, Handled, Point, Size, Vec2, Widget, WidgetId}; @@ -182,11 +182,24 @@ impl TestHarness { let _ = try_init_tracing(); let mut harness = TestHarness { - render_root: RenderRoot::new(root_widget, WindowSizePolicy::User, 1.0), + render_root: RenderRoot::new( + root_widget, + RenderRootOptions { + use_system_fonts: false, + size_policy: WindowSizePolicy::User, + scale_factor: 1.0, + }, + ), mouse_state, window_size, background_color, }; + const ROBOTO: &[u8] = include_bytes!(concat!( + env!("CARGO_MANIFEST_DIR"), + "/resources/fonts/roboto/Roboto-Regular.ttf" + )); + let data = ROBOTO.to_vec(); + harness.render_root.add_test_font(data); harness.process_window_event(WindowEvent::Resize(window_size)); harness @@ -243,6 +256,7 @@ impl TestHarness { if std::env::var("SKIP_RENDER_TESTS").is_ok_and(|it| !it.is_empty()) { return RgbaImage::from_pixel(1, 1, Rgba([255, 255, 255, 255])); } + // TODO: Cache/share the context let mut context = RenderContext::new(); let device_id = pollster::block_on(context.device(None)).expect("No compatible device found"); @@ -514,19 +528,14 @@ impl TestHarness { test_module_path: &str, test_name: &str, ) { - if option_env!("SKIP_RENDER_SNAPSHOTS").is_some() { - // FIXME - This is a terrible, awful hack. - // We need a way to skip render snapshots on CI and locally - // until we can make sure the snapshots render the same on - // different platforms. - + if std::env::var("SKIP_RENDER_TESTS").is_ok_and(|it| !it.is_empty()) { // We still redraw to get some coverage in the paint code. let _ = self.render_root.redraw(); return; } - let new_image = self.render(); + let new_image: DynamicImage = self.render().into(); let workspace_path = get_cargo_workspace(manifest_dir); let test_file_path_abs = workspace_path.join(test_file_path); @@ -541,16 +550,23 @@ impl TestHarness { let new_path = screenshots_folder.join(format!("{module_str}__{test_name}.new.png")); let diff_path = screenshots_folder.join(format!("{module_str}__{test_name}.diff.png")); + // TODO: If this file is corrupted, it could be an lfs bandwidth/installation issue. + // Have a warning for that case (i.e. differentiation between not-found and invalid format) + // and a environment variable to ignore the test in that case. if let Ok(reference_file) = ImageReader::open(reference_path) { - let ref_image = reference_file.decode().unwrap().to_rgba8(); + let ref_image = reference_file.decode().unwrap().to_rgb8(); - if let Some(diff_image) = get_image_diff(&ref_image, &new_image) { + if let Some(diff_image) = get_image_diff(&ref_image, &new_image.to_rgb8()) { // Remove '.new.png' '.diff.png' files if they exist let _ = std::fs::remove_file(&new_path); let _ = std::fs::remove_file(&diff_path); new_image.save(&new_path).unwrap(); diff_image.save(&diff_path).unwrap(); panic!("Images are different"); + } else { + // Remove the vestigal new and diff images + let _ = std::fs::remove_file(&new_path); + let _ = std::fs::remove_file(&diff_path); } } else { // Remove '.new.png' file if it exists diff --git a/masonry/src/testing/mod.rs b/masonry/src/testing/mod.rs index ce33eeeef..82d6bc06f 100644 --- a/masonry/src/testing/mod.rs +++ b/masonry/src/testing/mod.rs @@ -23,26 +23,3 @@ use crate::WidgetId; pub fn widget_ids() -> [WidgetId; N] { std::array::from_fn(|_| WidgetId::next()) } - -/// This function creates a temporary directory and returns a PathBuf to it. -/// -/// This directory will be created relative to the executable and will therefor -/// be created in the target directory for tests when running with cargo. The -/// directory will be cleaned up at the end of the PathBufs lifetime. This -/// uses the `tempfile` crate. -#[allow(dead_code)] -#[cfg(test)] -pub fn temp_dir_for_test() -> std::path::PathBuf { - let current_exe_path = std::env::current_exe().unwrap(); - let mut exe_dir = current_exe_path.parent().unwrap(); - if exe_dir.ends_with("deps") { - exe_dir = exe_dir.parent().unwrap(); - } - let test_dir = exe_dir.parent().unwrap().join("tests"); - std::fs::create_dir_all(&test_dir).unwrap(); - tempfile::Builder::new() - .prefix("TempDir") - .tempdir_in(test_dir) - .unwrap() - .into_path() -} diff --git a/masonry/src/testing/screenshots.rs b/masonry/src/testing/screenshots.rs index 3ff21a269..7d27efe6d 100644 --- a/masonry/src/testing/screenshots.rs +++ b/masonry/src/testing/screenshots.rs @@ -3,41 +3,49 @@ //! Helper functions for writing snapshot tests and comparing images. -use image::{GenericImageView as _, RgbaImage}; - -pub(crate) fn get_image_diff(ref_image: &RgbaImage, new_image: &RgbaImage) -> Option { - let mut is_changed = false; - - if ref_image.width() != new_image.width() || ref_image.height() != new_image.height() { - is_changed = true; +use image::{GenericImageView as _, RgbImage}; +use nv_flip::{FlipImageRgb8, DEFAULT_PIXELS_PER_DEGREE}; + +pub(crate) fn get_image_diff(ref_image: &RgbImage, new_image: &RgbImage) -> Option { + assert_eq!( + (ref_image.width(), ref_image.height()), + (new_image.width(), new_image.height()), + "New image (right) has different size from old image (left)." + ); + + let ref_image_flip = FlipImageRgb8::with_data(ref_image.width(), ref_image.height(), ref_image); + let new_image_flip = FlipImageRgb8::with_data(new_image.width(), new_image.height(), new_image); + let error_map = nv_flip::flip(ref_image_flip, new_image_flip, DEFAULT_PIXELS_PER_DEGREE); + let pool = nv_flip::FlipPool::from_image(&error_map); + let mean = pool.mean(); + + let is_changed = mean.abs() > 0.01; + + if !is_changed { + return None; } let width = std::cmp::max(ref_image.width(), new_image.width()); let height = std::cmp::max(ref_image.height(), new_image.height()); - let diff_image = RgbaImage::from_fn(width, height, |x, y| { + let diff_image = RgbImage::from_fn(width, height, |x, y| { let ref_pixel = if ref_image.in_bounds(x, y) { *ref_image.get_pixel(x, y) } else { - [0, 0, 0, 0].into() + [0, 0, 0].into() }; let new_pixel = if new_image.in_bounds(x, y) { *new_image.get_pixel(x, y) } else { - [255, 255, 255, 255].into() + [255, 255, 255].into() }; if new_pixel != ref_pixel { - is_changed = true; new_pixel } else { - [0, 0, 0, 0].into() + [0, 0, 0].into() } }); - if is_changed { - Some(diff_image) - } else { - None - } + Some(diff_image) } diff --git a/masonry/src/text_helpers.rs b/masonry/src/text_helpers.rs index 98ab5be1f..b9f50530e 100644 --- a/masonry/src/text_helpers.rs +++ b/masonry/src/text_helpers.rs @@ -98,6 +98,7 @@ pub fn render_text( scratch_scene .draw_glyphs(font) .brush(text_brush) + .hint(true) .transform(transform) .glyph_transform(glyph_xform) .font_size(font_size) diff --git a/masonry/src/widget/screenshots/masonry__widget__align__tests__centered.png b/masonry/src/widget/screenshots/masonry__widget__align__tests__centered.png index a563f8d10..89d16975f 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__align__tests__centered.png and b/masonry/src/widget/screenshots/masonry__widget__align__tests__centered.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__align__tests__left.png b/masonry/src/widget/screenshots/masonry__widget__align__tests__left.png index 093ee4186..f89f744a4 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__align__tests__left.png and b/masonry/src/widget/screenshots/masonry__widget__align__tests__left.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__align__tests__right.png b/masonry/src/widget/screenshots/masonry__widget__align__tests__right.png index 8241eb7a8..180947708 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__align__tests__right.png and b/masonry/src/widget/screenshots/masonry__widget__align__tests__right.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__button__tests__hello.png b/masonry/src/widget/screenshots/masonry__widget__button__tests__hello.png index 810e00fc1..ac7747017 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__button__tests__hello.png and b/masonry/src/widget/screenshots/masonry__widget__button__tests__hello.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__checkbox__tests__hello_checked.png b/masonry/src/widget/screenshots/masonry__widget__checkbox__tests__hello_checked.png index 7a4459d62..73e9ef4d7 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__checkbox__tests__hello_checked.png and b/masonry/src/widget/screenshots/masonry__widget__checkbox__tests__hello_checked.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__checkbox__tests__hello_unchecked.png b/masonry/src/widget/screenshots/masonry__widget__checkbox__tests__hello_unchecked.png index 775488c96..c29966c52 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__checkbox__tests__hello_unchecked.png and b/masonry/src/widget/screenshots/masonry__widget__checkbox__tests__hello_unchecked.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_baseline.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_baseline.png index 971944aa0..3e2b0c961 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_baseline.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_baseline.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_center.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_center.png index 971944aa0..3e2b0c961 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_center.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_center.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_end.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_end.png index 3df7d4dac..9b7c74ecf 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_end.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_end.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_fill.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_fill.png index c32af7964..c7050ad0a 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_fill.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_fill.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_start.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_start.png index c32af7964..c7050ad0a 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_start.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_cross_axis_start.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_fill_main_axis.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_fill_main_axis.png index 72493d89e..68485c8ff 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_fill_main_axis.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_fill_main_axis.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_center.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_center.png index ed4db56dd..1da0b432f 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_center.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_center.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_end.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_end.png index 636c159e3..21fd907c5 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_end.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_end.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceAround.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceAround.png index 72493d89e..68485c8ff 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceAround.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceAround.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceBetween.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceBetween.png index 1658b8e2e..2f95a3236 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceBetween.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceBetween.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceEvenly.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceEvenly.png index 0485cc59b..a848264af 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceEvenly.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_spaceEvenly.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_start.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_start.png index 971944aa0..3e2b0c961 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_start.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__col_main_axis_start.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_baseline.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_baseline.png index 3f551cec6..6722e57fb 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_baseline.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_baseline.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_center.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_center.png index 4d76e84ce..0b90d0b4b 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_center.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_center.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_end.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_end.png index fec059af8..a74b878d6 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_end.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_end.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_fill.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_fill.png index 3f551cec6..6722e57fb 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_fill.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_fill.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_start.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_start.png index 3f551cec6..6722e57fb 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_start.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_cross_axis_start.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_fill_main_axis.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_fill_main_axis.png index 9dd8b16e8..412c559b0 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_fill_main_axis.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_fill_main_axis.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_center.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_center.png index c790ad3cf..e28940e04 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_center.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_center.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_end.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_end.png index d9563b961..19b7161bb 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_end.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_end.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceAround.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceAround.png index 9dd8b16e8..412c559b0 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceAround.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceAround.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceBetween.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceBetween.png index 80429ccea..5684fade9 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceBetween.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceBetween.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceEvenly.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceEvenly.png index c7fdabb2d..59c612ed7 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceEvenly.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_spaceEvenly.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_start.png b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_start.png index 4d76e84ce..0b90d0b4b 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_start.png and b/masonry/src/widget/screenshots/masonry__widget__flex__tests__row_main_axis_start.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__image__tests__tall_paint.png b/masonry/src/widget/screenshots/masonry__widget__image__tests__tall_paint.png index 568bbd18a..3b562c18e 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__image__tests__tall_paint.png and b/masonry/src/widget/screenshots/masonry__widget__image__tests__tall_paint.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__label__tests__hello.png b/masonry/src/widget/screenshots/masonry__widget__label__tests__hello.png index 5aa1acd74..3a23b5921 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__label__tests__hello.png and b/masonry/src/widget/screenshots/masonry__widget__label__tests__hello.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__label__tests__line_break_modes.png b/masonry/src/widget/screenshots/masonry__widget__label__tests__line_break_modes.png index ba0767378..1e8bb3fef 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__label__tests__line_break_modes.png and b/masonry/src/widget/screenshots/masonry__widget__label__tests__line_break_modes.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__label__tests__styled_label.png b/masonry/src/widget/screenshots/masonry__widget__label__tests__styled_label.png index 20ff73819..bd8928fbb 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__label__tests__styled_label.png and b/masonry/src/widget/screenshots/masonry__widget__label__tests__styled_label.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_no_scroll.png b/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_no_scroll.png deleted file mode 100644 index 084c33d3c..000000000 Binary files a/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_no_scroll.png and /dev/null differ diff --git a/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_scroll_to_item_13.png b/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_scroll_to_item_13.png deleted file mode 100644 index e82bfa2da..000000000 Binary files a/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_scroll_to_item_13.png and /dev/null differ diff --git a/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_scroll_to_item_3.png b/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_scroll_to_item_3.png deleted file mode 100644 index 55b4da3c2..000000000 Binary files a/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_scroll_to_item_3.png and /dev/null differ diff --git a/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_scrolled.png b/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_scrolled.png deleted file mode 100644 index cb7169d2e..000000000 Binary files a/masonry/src/widget/screenshots/masonry__widget__portal__tests__button_list_scrolled.png and /dev/null differ diff --git a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_bottom.png b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_bottom.png index 1f148bd3a..c46678905 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_bottom.png and b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_bottom.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_default.png b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_default.png index b9234e42c..870694f7d 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_default.png and b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_default.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_down.png b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_down.png index a2f7accc8..0d5efae63 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_down.png and b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_down.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_horizontal.png b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_horizontal.png index 535c215b3..9ce1b84e3 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_horizontal.png and b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_horizontal.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_horizontal_middle.png b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_horizontal_middle.png index 2ffb18daa..e85cbccc2 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_horizontal_middle.png and b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_horizontal_middle.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_middle.png b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_middle.png index 0d1b7a55e..d26e3131c 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_middle.png and b/masonry/src/widget/screenshots/masonry__widget__scroll_bar__tests__scrollbar_middle.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__sized_box__tests__empty_box.png b/masonry/src/widget/screenshots/masonry__widget__sized_box__tests__empty_box.png index 25892e754..dc31f17ab 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__sized_box__tests__empty_box.png and b/masonry/src/widget/screenshots/masonry__widget__sized_box__tests__empty_box.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__sized_box__tests__label_box_no_size.png b/masonry/src/widget/screenshots/masonry__widget__sized_box__tests__label_box_no_size.png index 01b0bbe61..b28a2dfea 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__sized_box__tests__label_box_no_size.png and b/masonry/src/widget/screenshots/masonry__widget__sized_box__tests__label_box_no_size.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__spinner__tests__spinner_init.png b/masonry/src/widget/screenshots/masonry__widget__spinner__tests__spinner_init.png index 5aa4ae26d..e3babac22 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__spinner__tests__spinner_init.png and b/masonry/src/widget/screenshots/masonry__widget__spinner__tests__spinner_init.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__split__tests__columns.png b/masonry/src/widget/screenshots/masonry__widget__split__tests__columns.png index 15532cc51..a718df3af 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__split__tests__columns.png and b/masonry/src/widget/screenshots/masonry__widget__split__tests__columns.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__split__tests__rows.png b/masonry/src/widget/screenshots/masonry__widget__split__tests__rows.png index 574681d82..aeb26e315 100644 Binary files a/masonry/src/widget/screenshots/masonry__widget__split__tests__rows.png and b/masonry/src/widget/screenshots/masonry__widget__split__tests__rows.png differ diff --git a/masonry/src/widget/screenshots/masonry__widget__textbox__tests__hello.png b/masonry/src/widget/screenshots/masonry__widget__textbox__tests__hello.png deleted file mode 100644 index d2484cd7a..000000000 Binary files a/masonry/src/widget/screenshots/masonry__widget__textbox__tests__hello.png and /dev/null differ diff --git a/masonry/src/widget/screenshots/masonry__widget__textbox__tests__placeholder.png b/masonry/src/widget/screenshots/masonry__widget__textbox__tests__placeholder.png deleted file mode 100644 index 925dd52ed..000000000 Binary files a/masonry/src/widget/screenshots/masonry__widget__textbox__tests__placeholder.png and /dev/null differ diff --git a/masonry/src/widget/tests/safety_rails.rs b/masonry/src/widget/tests/safety_rails.rs index 77bd481b7..9b8e134c3 100644 --- a/masonry/src/widget/tests/safety_rails.rs +++ b/masonry/src/widget/tests/safety_rails.rs @@ -53,6 +53,10 @@ fn check_forget_to_recurse_text_event() { #[should_panic(expected = "not added in method lifecycle")] #[test] +#[cfg_attr( + not(debug_assertions), + ignore = "This test doesn't work without debug assertions (i.e. in release mode). See https://github.com/linebender/xilem/issues/477" +)] fn check_forget_to_recurse_lifecycle() { let widget = make_parent_widget(Flex::row()).lifecycle_fn(|_child, _ctx, _event| { // We forget to call child.lifecycle(); @@ -79,6 +83,10 @@ fn check_forget_to_recurse_widget_added() { #[should_panic(expected = "not visited in method layout")] #[test] +#[cfg_attr( + not(debug_assertions), + ignore = "This test doesn't work without debug assertions (i.e. in release mode). See https://github.com/linebender/xilem/issues/477" +)] fn check_forget_to_recurse_layout() { let widget = make_parent_widget(Flex::row()).layout_fn(|_child, _ctx, _| { // We forget to call child.layout(); @@ -90,6 +98,10 @@ fn check_forget_to_recurse_layout() { #[should_panic(expected = "missing call to place_child method for child widget")] #[test] +#[cfg_attr( + not(debug_assertions), + ignore = "This test doesn't work without debug assertions (i.e. in release mode). See https://github.com/linebender/xilem/issues/477" +)] fn check_forget_to_call_place_child() { let widget = make_parent_widget(Flex::row()).layout_fn(|child, ctx, bc| { // We call child.layout(), but forget place_child @@ -101,6 +113,10 @@ fn check_forget_to_call_place_child() { #[should_panic(expected = "not visited in method paint")] #[test] +#[cfg_attr( + not(debug_assertions), + ignore = "This test doesn't work without debug assertions (i.e. in release mode). See https://github.com/linebender/xilem/issues/477" +)] fn check_forget_to_recurse_paint() { let widget = make_parent_widget(Flex::row()).paint_fn(|_child, _ctx, _scene| { // We forget to call child.paint();