Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

View File

@@ -0,0 +1 @@
{"files":{"Cargo.lock":"e397194b866cb88e04fe62134a7cd7f8709fa003e535783132c645f5d39d5e14","Cargo.toml":"b7909fe36c8e95a33c34d816db2f72cf7f6074825cabccaa32ba36f110e34073","LICENSE-APACHE":"a6cba85bc92e0cff7a450b1d873c0eaa2e9fc96bf472df0247a26bec77bf3ff9","LICENSE-MIT":"508a77d2e7b51d98adeed32648ad124b7b30241a8e70b2e72c99f92d8e5874d1","README.md":"17cb917017064b09a445727e1f6a51d6ebdbaa2a2da24b3a1ffa142417868582","docs/conversion.md":"05eddd14cb6fa577870a262a431013c1bf7202b357c218a5a5ef0b796ddb060a","docs/diagrams/README.md":"3902b620b31fd550a3b303b994f35115a69f7a5e11f0b44e818b5acfc94d33c6","docs/diagrams/model_graph.mmd":"401172cb7b90d44eebb23988e0026592e58ddc861454a0549112c3c3971a04d4","docs/diagrams/model_graph.svg":"8dddbb19cde180f1fcdf713da72cf9639216f4708d388367b27277f67048b6e1","src/color.rs":"227069fc63b7e39a6465efb4cc087146cd37c3f1d161d85b5df221b798ea326d","src/color_difference.rs":"7111b96bb7230f01c90c5395a6b818fad554cbcaedaff69250d4e72119fb0b74","src/color_gradient.rs":"d82ac4b2ed5b4834dab587127f3d3a9e99ca6b0858c3632d6d7b14c66065684c","src/color_ops.rs":"a39fc65caef783323a2b03a51a9423a99c6d138a73e61d8e6509b14878121cfc","src/color_range.rs":"1862772e71c81d9964920c5f8af128a7f6654445d00c2c3bf35a6a8e16561348","src/hsla.rs":"3c159e3b314ed72303f8ea0108592a0147419a21e4de5549fad9ac4d3d0a3e9c","src/hsva.rs":"d5f3402b73f42c7ea5f3eb26b43ecd6a9d492d43a4cc337418ed09dcc4283cb6","src/hwba.rs":"8efc8720ebac8346cb2b92a62b9922461f3ab8739ec156798540bc7e5b15c194","src/laba.rs":"39369eaa3c24d74380a708e7ebd5d4c12d431e661d667ed5bc58821b7a3d7a18","src/lcha.rs":"1b8b93fda07a2fe6595edb37fec8a4d0462ff99b3e469b597d7835218af4da97","src/lib.rs":"9eefc4399e28467cd38e6e1dbd5157f19c4175dbef12fb2e24f9fcd1597cfa90","src/linear_rgba.rs":"1a3e1192aebb8ad1bde925ef1500df711ed422079d5bd438ff05c26fc516eccc","src/oklaba.rs":"faa244fe346a93a338c55e9c5f1b43ebdb0121019f02cd499a97e0cc876433d8","src/oklcha.rs":"6957074f2fdfac61dd542725fc3fa023ecfc5780495b47f733783e5d15fc301d","src/palettes/basic.rs":"bda1441bd7acff63b1cc80fc9cf74d98976c21a9b785d426e205029a0fca03dd","src/palettes/css.rs":"338ee9329cd0bc0d0b9ad973d75de7a9e458a4d3746aa685cd16fff2cee1b0f3","src/palettes/mod.rs":"df394e7f636a3c7f33a9bb8bb19abca474ad1cdc572af103f5d952a2939da304","src/palettes/tailwind.rs":"50cd110dd35ef816539d13f4b1738d3dc179830e6ad28da5e06f28a7585a2e84","src/srgba.rs":"06b1f0e5a71cae8916b7d13210a83228c9d33b3f73e7754f82e7728528930215","src/test_colors.rs":"1bef153ceeb73927d06caa88244069a84caef68dd2435cd4c434a395b96aed4a","src/testing.rs":"9975deba34e6373280deae7dc43fde5437ef854b2959335ce5c47d4025784066","src/xyza.rs":"aca823385af065f4ec8349aa48f6d9aaea5df9f4f390b89e0dd8f1662a17760a"},"package":"5c101cbe1e26b8d701eb77263b14346e2e0cbbd2a6e254b9b1aead814e5ca8d3"}

903
vendor/bevy_color/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,903 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "approx"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
dependencies = [
"num-traits",
]
[[package]]
name = "assert_type_match"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f548ad2c4031f2902e3edc1f29c29e835829437de49562d8eb5dc5584d3a1043"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bevy_color"
version = "0.16.2"
dependencies = [
"bevy_math",
"bevy_reflect",
"bytemuck",
"derive_more",
"encase",
"serde",
"thiserror 2.0.12",
"wgpu-types",
]
[[package]]
name = "bevy_macro_utils"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "052eeebcb8e7e072beea5031b227d9a290f8a7fbbb947573ab6ec81df0fb94be"
dependencies = [
"parking_lot",
"proc-macro2",
"quote",
"syn",
"toml_edit",
]
[[package]]
name = "bevy_math"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68553e0090fe9c3ba066c65629f636bd58e4ebd9444fdba097b91af6cd3e243f"
dependencies = [
"approx",
"bevy_reflect",
"derive_more",
"glam",
"itertools",
"libm",
"rand",
"rand_distr",
"serde",
"smallvec",
"thiserror 2.0.12",
"variadics_please",
]
[[package]]
name = "bevy_platform"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7573dc824a1b08b4c93fdbe421c53e1e8188e9ca1dd74a414455fe571facb47"
dependencies = [
"cfg-if",
"critical-section",
"foldhash",
"hashbrown",
"portable-atomic",
"portable-atomic-util",
"serde",
"spin",
]
[[package]]
name = "bevy_ptr"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df7370d0e46b60e071917711d0860721f5347bc958bf325975ae6913a5dfcf01"
[[package]]
name = "bevy_reflect"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daeb91a63a1a4df00aa58da8cc4ddbd4b9f16ab8bb647c5553eb156ce36fa8c2"
dependencies = [
"assert_type_match",
"bevy_platform",
"bevy_ptr",
"bevy_reflect_derive",
"bevy_utils",
"derive_more",
"disqualified",
"downcast-rs",
"erased-serde",
"foldhash",
"glam",
"serde",
"smol_str",
"thiserror 2.0.12",
"uuid",
"variadics_please",
"wgpu-types",
]
[[package]]
name = "bevy_reflect_derive"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ddadc55fe16b45faaa54ab2f9cb00548013c74812e8b018aa172387103cce6"
dependencies = [
"bevy_macro_utils",
"proc-macro2",
"quote",
"syn",
"uuid",
]
[[package]]
name = "bevy_utils"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94f7a8905a125d2017e8561beefb7f2f5e67e93ff6324f072ad87c5fd6ec3b99"
dependencies = [
"bevy_platform",
"thread_local",
]
[[package]]
name = "bitflags"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
dependencies = [
"serde",
]
[[package]]
name = "bumpalo"
version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "bytemuck"
version = "1.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ecc273b49b3205b83d648f0690daa588925572cc5063745bfe547fe7ec8e1a1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "const_panic"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2459fc9262a1aa204eb4b5764ad4f189caec88aea9634389c0a25f8be7f6265e"
[[package]]
name = "critical-section"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
[[package]]
name = "derive_more"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
dependencies = [
"derive_more-impl",
]
[[package]]
name = "derive_more-impl"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "disqualified"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9c272297e804878a2a4b707cfcfc6d2328b5bb936944613b4fdf2b9269afdfd"
[[package]]
name = "downcast-rs"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea8a8b81cacc08888170eef4d13b775126db426d0b348bee9d18c2c1eaf123cf"
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "encase"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0a05902cf601ed11d564128448097b98ebe3c6574bd7b6a653a3d56d54aa020"
dependencies = [
"const_panic",
"encase_derive",
"thiserror 1.0.69",
]
[[package]]
name = "encase_derive"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "181d475b694e2dd56ae919ce7699d344d1fd259292d590c723a50d1189a2ea85"
dependencies = [
"encase_derive_impl",
]
[[package]]
name = "encase_derive_impl"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f97b51c5cc57ef7c5f7a0c57c250251c49ee4c28f819f87ac32f4aceabc36792"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "erased-serde"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"
dependencies = [
"serde",
"typeid",
]
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "getrandom"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
"cfg-if",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
]
[[package]]
name = "glam"
version = "0.29.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8babf46d4c1c9d92deac9f7be466f76dfc4482b6452fc5024b5e8daf6ffeb3ee"
dependencies = [
"bytemuck",
"libm",
"serde",
]
[[package]]
name = "hashbrown"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
dependencies = [
"equivalent",
"serde",
]
[[package]]
name = "indexmap"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]]
name = "js-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.172"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
[[package]]
name = "libm"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
[[package]]
name = "lock_api"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
version = "2.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "parking_lot"
version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"smallvec",
"windows-targets",
]
[[package]]
name = "portable-atomic"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e"
dependencies = [
"critical-section",
]
[[package]]
name = "portable-atomic-util"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
dependencies = [
"portable-atomic",
]
[[package]]
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro2"
version = "1.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom 0.2.16",
]
[[package]]
name = "rand_distr"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
dependencies = [
"num-traits",
"rand",
]
[[package]]
name = "redox_syscall"
version = "0.5.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
dependencies = [
"bitflags",
]
[[package]]
name = "rustversion"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"
[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "smallvec"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
[[package]]
name = "smol_str"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd538fb6910ac1099850255cf94a94df6551fbdd602454387d0adb2d1ca6dead"
dependencies = [
"serde",
]
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
dependencies = [
"portable-atomic",
]
[[package]]
name = "syn"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl 2.0.12",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thiserror-impl"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "1.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
dependencies = [
"cfg-if",
"once_cell",
]
[[package]]
name = "toml_datetime"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3"
[[package]]
name = "toml_edit"
version = "0.22.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e"
dependencies = [
"indexmap",
"toml_datetime",
"winnow",
]
[[package]]
name = "typeid"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "uuid"
version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
dependencies = [
"getrandom 0.3.3",
"js-sys",
"serde",
"wasm-bindgen",
]
[[package]]
name = "variadics_please"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41b6d82be61465f97d42bd1d15bf20f3b0a3a0905018f38f9d6f6962055b0b5c"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
"unicode-ident",
]
[[package]]
name = "web-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "wgpu-types"
version = "24.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50ac044c0e76c03a0378e7786ac505d010a873665e2d51383dcff8dd227dc69c"
dependencies = [
"bitflags",
"js-sys",
"log",
"serde",
"web-sys",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen-rt"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags",
]
[[package]]
name = "zerocopy"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

148
vendor/bevy_color/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,148 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2024"
rust-version = "1.85.0"
name = "bevy_color"
version = "0.16.2"
build = false
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Types for representing and manipulating color values"
homepage = "https://bevyengine.org"
readme = "README.md"
keywords = [
"bevy",
"color",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/bevyengine/bevy"
resolver = "2"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
"-Zunstable-options",
"--generate-link-to-definition",
]
[features]
alloc = [
"bevy_math/alloc",
"serde?/alloc",
]
bevy_reflect = ["dep:bevy_reflect"]
critical-section = ["bevy_reflect?/critical-section"]
default = [
"std",
"bevy_reflect",
"encase",
]
encase = [
"dep:encase",
"std",
]
libm = ["bevy_math/libm"]
serialize = [
"serde",
"bevy_math/serialize",
]
std = [
"alloc",
"bevy_math/std",
"serde?/std",
"wgpu-types?/std",
"bevy_reflect?/std",
]
wgpu-types = ["dep:wgpu-types"]
[lib]
name = "bevy_color"
path = "src/lib.rs"
[dependencies.bevy_math]
version = "0.16.1"
features = ["curve"]
default-features = false
[dependencies.bevy_reflect]
version = "0.16.1"
optional = true
default-features = false
[dependencies.bytemuck]
version = "1"
features = ["derive"]
[dependencies.derive_more]
version = "1"
features = ["from"]
default-features = false
[dependencies.encase]
version = "0.10"
optional = true
default-features = false
[dependencies.serde]
version = "1.0"
features = ["derive"]
optional = true
default-features = false
[dependencies.thiserror]
version = "2"
default-features = false
[dependencies.wgpu-types]
version = "24"
optional = true
default-features = false
[lints.clippy]
alloc_instead_of_core = "warn"
allow_attributes = "warn"
allow_attributes_without_reason = "warn"
doc_markdown = "warn"
manual_let_else = "warn"
match_same_arms = "warn"
needless_lifetimes = "allow"
nonstandard_macro_braces = "warn"
print_stderr = "warn"
print_stdout = "warn"
ptr_as_ptr = "warn"
ptr_cast_constness = "warn"
redundant_closure_for_method_calls = "warn"
redundant_else = "warn"
ref_as_ptr = "warn"
semicolon_if_nothing_returned = "warn"
std_instead_of_alloc = "warn"
std_instead_of_core = "warn"
too_long_first_doc_paragraph = "allow"
too_many_arguments = "allow"
type_complexity = "allow"
undocumented_unsafe_blocks = "warn"
unwrap_or_default = "warn"
[lints.rust]
missing_docs = "warn"
unsafe_code = "deny"
unsafe_op_in_unsafe_fn = "warn"
unused_qualifications = "warn"
[lints.rust.unexpected_cfgs]
level = "warn"
priority = 0
check-cfg = ["cfg(docsrs_dep)"]

176
vendor/bevy_color/LICENSE-APACHE vendored Normal file
View File

@@ -0,0 +1,176 @@
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

19
vendor/bevy_color/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,19 @@
MIT License
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.

7
vendor/bevy_color/README.md vendored Normal file
View File

@@ -0,0 +1,7 @@
# Bevy Color
[![License](https://img.shields.io/badge/license-MIT%2FApache-blue.svg)](https://github.com/bevyengine/bevy#license)
[![Crates.io](https://img.shields.io/crates/v/bevy_color.svg)](https://crates.io/crates/bevy_color)
[![Downloads](https://img.shields.io/crates/d/bevy_color.svg)](https://crates.io/crates/bevy_color)
[![Docs](https://docs.rs/bevy_color/badge.svg)](https://docs.rs/bevy_color/latest/bevy_color/)
[![Discord](https://img.shields.io/discord/691052431525675048.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/bevy)

16
vendor/bevy_color/docs/conversion.md vendored Normal file
View File

@@ -0,0 +1,16 @@
# Conversion
Conversion between the various color spaces is achieved using Rust's native [From] trait. Because certain color spaces are defined by their transformation to and from another space, these [From] implementations reflect that set of definitions.
```rust
# use bevy_color::{Srgba, LinearRgba};
let color = Srgba::rgb(0.5, 0.5, 0.5);
// Using From explicitly
let linear_color = LinearRgba::from(color);
// Using Into
let linear_color: LinearRgba = color.into();
```
For example, the [sRGB](crate::Srgba) space is defined by its relationship with [Linear RGB](crate::LinearRgba), and [HWB](crate::Hwba) by its with [sRGB](crate::Srgba). As such, it is the responsibility of [sRGB](crate::Srgba) to provide [From] implementations for [Linear RGB](crate::LinearRgba), and [HWB](crate::Hwba) for [sRGB](crate::Srgba). To then provide conversion between [Linear RGB](crate::LinearRgba) and [HWB](crate::Hwba) directly, [HWB](crate::Hwba) is responsible for implementing these conversions, delegating to [sRGB](crate::Srgba) as an intermediatory. This ensures that all conversions take the shortest path between any two spaces, and limit the proliferation of domain specific knowledge for each color space to their respective definitions.

View File

@@ -0,0 +1,3 @@
# Creating Mermaid Diagrams
Mermaid diagrams (`.mmd` files) can be converted to SVG using various tools. The simplest to work with is [mermaid.live](https://mermaid.live/), which is a HTML web app. When editing `.mmd` files, make sure to regenerate the associated SVGs.

View File

@@ -0,0 +1,22 @@
%%{ init: { 'theme': 'dark', 'flowchart': { 'curve': 'stepAfter', 'padding': 30 }, 'themeCSS': '.label foreignObject { overflow: visible; }' } }%%
flowchart LR
lRGB(<a href='https://en.wikipedia.org/wiki/Rgb'>Linear<br/>sRGB</a>)
Oklab(<a href='https://oklch.com/'>Oklab</a>)
Oklch(<a href='https://oklch.com/'>Oklch</a>)
XYZ(<a href='https://en.wikipedia.org/wiki/XYZ_color'>XYZ</a>)
Lab(<a href='https://en.wikipedia.org/wiki/Lab_color'>Lab</a>)
Lch(<a href='https://en.wikipedia.org/wiki/CIELAB_color_space#Cylindrical_model'>Lch</a>)
sRGB(<a href='https://en.wikipedia.org/wiki/Srgb'>sRGB</a>)
HWB(<a href='https://en.wikipedia.org/wiki/HWB_color_model'>HWB</a>)
HSV(<a href='https://en.wikipedia.org/wiki/HSL_and_HSV'>HSV</a>)
HSL(<a href='https://en.wikipedia.org/wiki/HSL_and_HSV'>HSL</a>)
GPU <--> lRGB
lRGB <--<a href='https://bottosson.github.io/posts/oklab/#converting-from-linear-srgb-to-oklab'>Conversion</a>--> Oklab
Oklab <--<a href='https://bottosson.github.io/posts/oklab/#the-oklab-color-space'>Conversion</a>--> Oklch
lRGB <--<a href='http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html'>Conversion</a>--> XYZ
XYZ <--<a href='http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html'>Conversion</a>--> Lab
Lab <--<a href='http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html'>Conversion</a>--> Lch
lRGB <--<a href='https://en.wikipedia.org/wiki/SRGB#From_sRGB_to_CIE_XYZ'>Conversion</a>--> sRGB
sRGB <--<a href='http://alvyray.com/Papers/CG/HWB_JGTv208.pdf'>Conversion</a>--> HWB
HWB <--<a href='http://alvyray.com/Papers/CG/HWB_JGTv208.pdf'>Conversion</a>--> HSV
HSV <--<a href='https://en.wikipedia.org/wiki/HSL_and_HSV#Interconversion'>Conversion</a>--> HSL

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 19 KiB

891
vendor/bevy_color/src/color.rs vendored Normal file
View File

@@ -0,0 +1,891 @@
use crate::{
color_difference::EuclideanDistance, Alpha, Hsla, Hsva, Hue, Hwba, Laba, Lcha, LinearRgba,
Luminance, Mix, Oklaba, Oklcha, Saturation, Srgba, StandardColor, Xyza,
};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
use derive_more::derive::From;
/// An enumerated type that can represent any of the color types in this crate.
///
/// This is useful when you need to store a color in a data structure that can't be generic over
/// the color type.
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
///
/// # Operations
///
/// [`Color`] supports all the standard color operations, such as [mixing](Mix),
/// [luminance](Luminance) and [hue](Hue) adjustment,
/// and [diffing](EuclideanDistance). These operations delegate to the concrete color space contained
/// by [`Color`], but will convert to [`Oklch`](Oklcha) for operations which aren't supported in the
/// current space. After performing the operation, if a conversion was required, the result will be
/// converted back into the original color space.
///
/// ```rust
/// # use bevy_color::{Hue, Color};
/// let red_hsv = Color::hsv(0., 1., 1.);
/// let red_srgb = Color::srgb(1., 0., 0.);
///
/// // HSV has a definition of hue, so it will be returned.
/// red_hsv.hue();
///
/// // SRGB doesn't have a native definition for hue.
/// // Converts to Oklch and returns that result.
/// red_srgb.hue();
/// ```
///
/// [`Oklch`](Oklcha) has been chosen as the intermediary space in cases where conversion is required
/// due to its perceptual uniformity and broad support for Bevy's color operations.
/// To avoid the cost of repeated conversion, and ensure consistent results where that is desired,
/// first convert this [`Color`] into your desired color space.
#[derive(Debug, Clone, Copy, PartialEq, From)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub enum Color {
/// A color in the sRGB color space with alpha.
Srgba(Srgba),
/// A color in the linear sRGB color space with alpha.
LinearRgba(LinearRgba),
/// A color in the HSL color space with alpha.
Hsla(Hsla),
/// A color in the HSV color space with alpha.
Hsva(Hsva),
/// A color in the HWB color space with alpha.
Hwba(Hwba),
/// A color in the LAB color space with alpha.
Laba(Laba),
/// A color in the LCH color space with alpha.
Lcha(Lcha),
/// A color in the Oklab color space with alpha.
Oklaba(Oklaba),
/// A color in the Oklch color space with alpha.
Oklcha(Oklcha),
/// A color in the XYZ color space with alpha.
Xyza(Xyza),
}
impl StandardColor for Color {}
impl Color {
/// Return the color as a linear RGBA color.
pub fn to_linear(&self) -> LinearRgba {
(*self).into()
}
/// Return the color as an SRGBA color.
pub fn to_srgba(&self) -> Srgba {
(*self).into()
}
/// Creates a new [`Color`] object storing a [`Srgba`] color.
///
/// # Arguments
///
/// * `red` - Red channel. [0.0, 1.0]
/// * `green` - Green channel. [0.0, 1.0]
/// * `blue` - Blue channel. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn srgba(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
Self::Srgba(Srgba {
red,
green,
blue,
alpha,
})
}
/// Creates a new [`Color`] object storing a [`Srgba`] color with an alpha of 1.0.
///
/// # Arguments
///
/// * `red` - Red channel. [0.0, 1.0]
/// * `green` - Green channel. [0.0, 1.0]
/// * `blue` - Blue channel. [0.0, 1.0]
pub const fn srgb(red: f32, green: f32, blue: f32) -> Self {
Self::Srgba(Srgba {
red,
green,
blue,
alpha: 1.0,
})
}
/// Reads an array of floats to creates a new [`Color`] object storing a [`Srgba`] color with an alpha of 1.0.
///
/// # Arguments
/// * `array` - Red, Green and Blue channels. Each channel is in the range [0.0, 1.0]
pub const fn srgb_from_array(array: [f32; 3]) -> Self {
Self::Srgba(Srgba {
red: array[0],
green: array[1],
blue: array[2],
alpha: 1.0,
})
}
/// Creates a new [`Color`] object storing a [`Srgba`] color from [`u8`] values.
///
/// # Arguments
///
/// * `red` - Red channel. [0, 255]
/// * `green` - Green channel. [0, 255]
/// * `blue` - Blue channel. [0, 255]
/// * `alpha` - Alpha channel. [0, 255]
pub const fn srgba_u8(red: u8, green: u8, blue: u8, alpha: u8) -> Self {
Self::Srgba(Srgba {
red: red as f32 / 255.0,
green: green as f32 / 255.0,
blue: blue as f32 / 255.0,
alpha: alpha as f32 / 255.0,
})
}
/// Creates a new [`Color`] object storing a [`Srgba`] color from [`u8`] values with an alpha of 1.0.
///
/// # Arguments
///
/// * `red` - Red channel. [0, 255]
/// * `green` - Green channel. [0, 255]
/// * `blue` - Blue channel. [0, 255]
pub const fn srgb_u8(red: u8, green: u8, blue: u8) -> Self {
Self::Srgba(Srgba {
red: red as f32 / 255.0,
green: green as f32 / 255.0,
blue: blue as f32 / 255.0,
alpha: 1.0,
})
}
/// Creates a new [`Color`] object storing a [`LinearRgba`] color.
///
/// # Arguments
///
/// * `red` - Red channel. [0.0, 1.0]
/// * `green` - Green channel. [0.0, 1.0]
/// * `blue` - Blue channel. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn linear_rgba(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
Self::LinearRgba(LinearRgba {
red,
green,
blue,
alpha,
})
}
/// Creates a new [`Color`] object storing a [`LinearRgba`] color with an alpha of 1.0.
///
/// # Arguments
///
/// * `red` - Red channel. [0.0, 1.0]
/// * `green` - Green channel. [0.0, 1.0]
/// * `blue` - Blue channel. [0.0, 1.0]
pub const fn linear_rgb(red: f32, green: f32, blue: f32) -> Self {
Self::LinearRgba(LinearRgba {
red,
green,
blue,
alpha: 1.0,
})
}
/// Creates a new [`Color`] object storing a [`Hsla`] color.
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `saturation` - Saturation channel. [0.0, 1.0]
/// * `lightness` - Lightness channel. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn hsla(hue: f32, saturation: f32, lightness: f32, alpha: f32) -> Self {
Self::Hsla(Hsla {
hue,
saturation,
lightness,
alpha,
})
}
/// Creates a new [`Color`] object storing a [`Hsla`] color with an alpha of 1.0.
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `saturation` - Saturation channel. [0.0, 1.0]
/// * `lightness` - Lightness channel. [0.0, 1.0]
pub const fn hsl(hue: f32, saturation: f32, lightness: f32) -> Self {
Self::Hsla(Hsla {
hue,
saturation,
lightness,
alpha: 1.0,
})
}
/// Creates a new [`Color`] object storing a [`Hsva`] color.
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `saturation` - Saturation channel. [0.0, 1.0]
/// * `value` - Value channel. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn hsva(hue: f32, saturation: f32, value: f32, alpha: f32) -> Self {
Self::Hsva(Hsva {
hue,
saturation,
value,
alpha,
})
}
/// Creates a new [`Color`] object storing a [`Hsva`] color with an alpha of 1.0.
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `saturation` - Saturation channel. [0.0, 1.0]
/// * `value` - Value channel. [0.0, 1.0]
pub const fn hsv(hue: f32, saturation: f32, value: f32) -> Self {
Self::Hsva(Hsva {
hue,
saturation,
value,
alpha: 1.0,
})
}
/// Creates a new [`Color`] object storing a [`Hwba`] color.
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `whiteness` - Whiteness channel. [0.0, 1.0]
/// * `blackness` - Blackness channel. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn hwba(hue: f32, whiteness: f32, blackness: f32, alpha: f32) -> Self {
Self::Hwba(Hwba {
hue,
whiteness,
blackness,
alpha,
})
}
/// Creates a new [`Color`] object storing a [`Hwba`] color with an alpha of 1.0.
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `whiteness` - Whiteness channel. [0.0, 1.0]
/// * `blackness` - Blackness channel. [0.0, 1.0]
pub const fn hwb(hue: f32, whiteness: f32, blackness: f32) -> Self {
Self::Hwba(Hwba {
hue,
whiteness,
blackness,
alpha: 1.0,
})
}
/// Creates a new [`Color`] object storing a [`Laba`] color.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.5]
/// * `a` - a axis. [-1.5, 1.5]
/// * `b` - b axis. [-1.5, 1.5]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn laba(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
Self::Laba(Laba {
lightness,
a,
b,
alpha,
})
}
/// Creates a new [`Color`] object storing a [`Laba`] color with an alpha of 1.0.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.5]
/// * `a` - a axis. [-1.5, 1.5]
/// * `b` - b axis. [-1.5, 1.5]
pub const fn lab(lightness: f32, a: f32, b: f32) -> Self {
Self::Laba(Laba {
lightness,
a,
b,
alpha: 1.0,
})
}
/// Creates a new [`Color`] object storing a [`Lcha`] color.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.5]
/// * `chroma` - Chroma channel. [0.0, 1.5]
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn lcha(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> Self {
Self::Lcha(Lcha {
lightness,
chroma,
hue,
alpha,
})
}
/// Creates a new [`Color`] object storing a [`Lcha`] color with an alpha of 1.0.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.5]
/// * `chroma` - Chroma channel. [0.0, 1.5]
/// * `hue` - Hue channel. [0.0, 360.0]
pub const fn lch(lightness: f32, chroma: f32, hue: f32) -> Self {
Self::Lcha(Lcha {
lightness,
chroma,
hue,
alpha: 1.0,
})
}
/// Creates a new [`Color`] object storing a [`Oklaba`] color.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.0]
/// * `a` - Green-red channel. [-1.0, 1.0]
/// * `b` - Blue-yellow channel. [-1.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn oklaba(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
Self::Oklaba(Oklaba {
lightness,
a,
b,
alpha,
})
}
/// Creates a new [`Color`] object storing a [`Oklaba`] color with an alpha of 1.0.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.0]
/// * `a` - Green-red channel. [-1.0, 1.0]
/// * `b` - Blue-yellow channel. [-1.0, 1.0]
pub const fn oklab(lightness: f32, a: f32, b: f32) -> Self {
Self::Oklaba(Oklaba {
lightness,
a,
b,
alpha: 1.0,
})
}
/// Creates a new [`Color`] object storing a [`Oklcha`] color.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.0]
/// * `chroma` - Chroma channel. [0.0, 1.0]
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn oklcha(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> Self {
Self::Oklcha(Oklcha {
lightness,
chroma,
hue,
alpha,
})
}
/// Creates a new [`Color`] object storing a [`Oklcha`] color with an alpha of 1.0.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.0]
/// * `chroma` - Chroma channel. [0.0, 1.0]
/// * `hue` - Hue channel. [0.0, 360.0]
pub const fn oklch(lightness: f32, chroma: f32, hue: f32) -> Self {
Self::Oklcha(Oklcha {
lightness,
chroma,
hue,
alpha: 1.0,
})
}
/// Creates a new [`Color`] object storing a [`Xyza`] color.
///
/// # Arguments
///
/// * `x` - x-axis. [0.0, 1.0]
/// * `y` - y-axis. [0.0, 1.0]
/// * `z` - z-axis. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn xyza(x: f32, y: f32, z: f32, alpha: f32) -> Self {
Self::Xyza(Xyza { x, y, z, alpha })
}
/// Creates a new [`Color`] object storing a [`Xyza`] color with an alpha of 1.0.
///
/// # Arguments
///
/// * `x` - x-axis. [0.0, 1.0]
/// * `y` - y-axis. [0.0, 1.0]
/// * `z` - z-axis. [0.0, 1.0]
pub const fn xyz(x: f32, y: f32, z: f32) -> Self {
Self::Xyza(Xyza {
x,
y,
z,
alpha: 1.0,
})
}
/// A fully white [`Color::LinearRgba`] color with an alpha of 1.0.
pub const WHITE: Self = Self::linear_rgb(1.0, 1.0, 1.0);
/// A fully black [`Color::LinearRgba`] color with an alpha of 1.0.
pub const BLACK: Self = Self::linear_rgb(0., 0., 0.);
/// A fully transparent [`Color::LinearRgba`] color with 0 red, green and blue.
pub const NONE: Self = Self::linear_rgba(0., 0., 0., 0.);
}
impl Default for Color {
/// A fully white [`Color::LinearRgba`] color with an alpha of 1.0.
fn default() -> Self {
Color::WHITE
}
}
impl Alpha for Color {
fn with_alpha(&self, alpha: f32) -> Self {
let mut new = *self;
match &mut new {
Color::Srgba(x) => *x = x.with_alpha(alpha),
Color::LinearRgba(x) => *x = x.with_alpha(alpha),
Color::Hsla(x) => *x = x.with_alpha(alpha),
Color::Hsva(x) => *x = x.with_alpha(alpha),
Color::Hwba(x) => *x = x.with_alpha(alpha),
Color::Laba(x) => *x = x.with_alpha(alpha),
Color::Lcha(x) => *x = x.with_alpha(alpha),
Color::Oklaba(x) => *x = x.with_alpha(alpha),
Color::Oklcha(x) => *x = x.with_alpha(alpha),
Color::Xyza(x) => *x = x.with_alpha(alpha),
}
new
}
fn alpha(&self) -> f32 {
match self {
Color::Srgba(x) => x.alpha(),
Color::LinearRgba(x) => x.alpha(),
Color::Hsla(x) => x.alpha(),
Color::Hsva(x) => x.alpha(),
Color::Hwba(x) => x.alpha(),
Color::Laba(x) => x.alpha(),
Color::Lcha(x) => x.alpha(),
Color::Oklaba(x) => x.alpha(),
Color::Oklcha(x) => x.alpha(),
Color::Xyza(x) => x.alpha(),
}
}
fn set_alpha(&mut self, alpha: f32) {
match self {
Color::Srgba(x) => x.set_alpha(alpha),
Color::LinearRgba(x) => x.set_alpha(alpha),
Color::Hsla(x) => x.set_alpha(alpha),
Color::Hsva(x) => x.set_alpha(alpha),
Color::Hwba(x) => x.set_alpha(alpha),
Color::Laba(x) => x.set_alpha(alpha),
Color::Lcha(x) => x.set_alpha(alpha),
Color::Oklaba(x) => x.set_alpha(alpha),
Color::Oklcha(x) => x.set_alpha(alpha),
Color::Xyza(x) => x.set_alpha(alpha),
}
}
}
impl From<Color> for Srgba {
fn from(value: Color) -> Self {
match value {
Color::Srgba(srgba) => srgba,
Color::LinearRgba(linear) => linear.into(),
Color::Hsla(hsla) => hsla.into(),
Color::Hsva(hsva) => hsva.into(),
Color::Hwba(hwba) => hwba.into(),
Color::Laba(laba) => laba.into(),
Color::Lcha(lcha) => lcha.into(),
Color::Oklaba(oklab) => oklab.into(),
Color::Oklcha(oklch) => oklch.into(),
Color::Xyza(xyza) => xyza.into(),
}
}
}
impl From<Color> for LinearRgba {
fn from(value: Color) -> Self {
match value {
Color::Srgba(srgba) => srgba.into(),
Color::LinearRgba(linear) => linear,
Color::Hsla(hsla) => hsla.into(),
Color::Hsva(hsva) => hsva.into(),
Color::Hwba(hwba) => hwba.into(),
Color::Laba(laba) => laba.into(),
Color::Lcha(lcha) => lcha.into(),
Color::Oklaba(oklab) => oklab.into(),
Color::Oklcha(oklch) => oklch.into(),
Color::Xyza(xyza) => xyza.into(),
}
}
}
impl From<Color> for Hsla {
fn from(value: Color) -> Self {
match value {
Color::Srgba(srgba) => srgba.into(),
Color::LinearRgba(linear) => linear.into(),
Color::Hsla(hsla) => hsla,
Color::Hsva(hsva) => hsva.into(),
Color::Hwba(hwba) => hwba.into(),
Color::Laba(laba) => laba.into(),
Color::Lcha(lcha) => lcha.into(),
Color::Oklaba(oklab) => oklab.into(),
Color::Oklcha(oklch) => oklch.into(),
Color::Xyza(xyza) => xyza.into(),
}
}
}
impl From<Color> for Hsva {
fn from(value: Color) -> Self {
match value {
Color::Srgba(srgba) => srgba.into(),
Color::LinearRgba(linear) => linear.into(),
Color::Hsla(hsla) => hsla.into(),
Color::Hsva(hsva) => hsva,
Color::Hwba(hwba) => hwba.into(),
Color::Laba(laba) => laba.into(),
Color::Lcha(lcha) => lcha.into(),
Color::Oklaba(oklab) => oklab.into(),
Color::Oklcha(oklch) => oklch.into(),
Color::Xyza(xyza) => xyza.into(),
}
}
}
impl From<Color> for Hwba {
fn from(value: Color) -> Self {
match value {
Color::Srgba(srgba) => srgba.into(),
Color::LinearRgba(linear) => linear.into(),
Color::Hsla(hsla) => hsla.into(),
Color::Hsva(hsva) => hsva.into(),
Color::Hwba(hwba) => hwba,
Color::Laba(laba) => laba.into(),
Color::Lcha(lcha) => lcha.into(),
Color::Oklaba(oklab) => oklab.into(),
Color::Oklcha(oklch) => oklch.into(),
Color::Xyza(xyza) => xyza.into(),
}
}
}
impl From<Color> for Laba {
fn from(value: Color) -> Self {
match value {
Color::Srgba(srgba) => srgba.into(),
Color::LinearRgba(linear) => linear.into(),
Color::Hsla(hsla) => hsla.into(),
Color::Hsva(hsva) => hsva.into(),
Color::Hwba(hwba) => hwba.into(),
Color::Laba(laba) => laba,
Color::Lcha(lcha) => lcha.into(),
Color::Oklaba(oklab) => oklab.into(),
Color::Oklcha(oklch) => oklch.into(),
Color::Xyza(xyza) => xyza.into(),
}
}
}
impl From<Color> for Lcha {
fn from(value: Color) -> Self {
match value {
Color::Srgba(srgba) => srgba.into(),
Color::LinearRgba(linear) => linear.into(),
Color::Hsla(hsla) => hsla.into(),
Color::Hsva(hsva) => hsva.into(),
Color::Hwba(hwba) => hwba.into(),
Color::Laba(laba) => laba.into(),
Color::Lcha(lcha) => lcha,
Color::Oklaba(oklab) => oklab.into(),
Color::Oklcha(oklch) => oklch.into(),
Color::Xyza(xyza) => xyza.into(),
}
}
}
impl From<Color> for Oklaba {
fn from(value: Color) -> Self {
match value {
Color::Srgba(srgba) => srgba.into(),
Color::LinearRgba(linear) => linear.into(),
Color::Hsla(hsla) => hsla.into(),
Color::Hsva(hsva) => hsva.into(),
Color::Hwba(hwba) => hwba.into(),
Color::Laba(laba) => laba.into(),
Color::Lcha(lcha) => lcha.into(),
Color::Oklaba(oklab) => oklab,
Color::Oklcha(oklch) => oklch.into(),
Color::Xyza(xyza) => xyza.into(),
}
}
}
impl From<Color> for Oklcha {
fn from(value: Color) -> Self {
match value {
Color::Srgba(srgba) => srgba.into(),
Color::LinearRgba(linear) => linear.into(),
Color::Hsla(hsla) => hsla.into(),
Color::Hsva(hsva) => hsva.into(),
Color::Hwba(hwba) => hwba.into(),
Color::Laba(laba) => laba.into(),
Color::Lcha(lcha) => lcha.into(),
Color::Oklaba(oklab) => oklab.into(),
Color::Oklcha(oklch) => oklch,
Color::Xyza(xyza) => xyza.into(),
}
}
}
impl From<Color> for Xyza {
fn from(value: Color) -> Self {
match value {
Color::Srgba(x) => x.into(),
Color::LinearRgba(x) => x.into(),
Color::Hsla(x) => x.into(),
Color::Hsva(hsva) => hsva.into(),
Color::Hwba(hwba) => hwba.into(),
Color::Laba(laba) => laba.into(),
Color::Lcha(x) => x.into(),
Color::Oklaba(x) => x.into(),
Color::Oklcha(oklch) => oklch.into(),
Color::Xyza(xyza) => xyza,
}
}
}
/// Color space chosen for operations on `Color`.
type ChosenColorSpace = Oklcha;
impl Luminance for Color {
fn luminance(&self) -> f32 {
match self {
Color::Srgba(x) => x.luminance(),
Color::LinearRgba(x) => x.luminance(),
Color::Hsla(x) => x.luminance(),
Color::Hsva(x) => ChosenColorSpace::from(*x).luminance(),
Color::Hwba(x) => ChosenColorSpace::from(*x).luminance(),
Color::Laba(x) => x.luminance(),
Color::Lcha(x) => x.luminance(),
Color::Oklaba(x) => x.luminance(),
Color::Oklcha(x) => x.luminance(),
Color::Xyza(x) => x.luminance(),
}
}
fn with_luminance(&self, value: f32) -> Self {
let mut new = *self;
match &mut new {
Color::Srgba(x) => *x = x.with_luminance(value),
Color::LinearRgba(x) => *x = x.with_luminance(value),
Color::Hsla(x) => *x = x.with_luminance(value),
Color::Hsva(x) => *x = ChosenColorSpace::from(*x).with_luminance(value).into(),
Color::Hwba(x) => *x = ChosenColorSpace::from(*x).with_luminance(value).into(),
Color::Laba(x) => *x = x.with_luminance(value),
Color::Lcha(x) => *x = x.with_luminance(value),
Color::Oklaba(x) => *x = x.with_luminance(value),
Color::Oklcha(x) => *x = x.with_luminance(value),
Color::Xyza(x) => *x = x.with_luminance(value),
}
new
}
fn darker(&self, amount: f32) -> Self {
let mut new = *self;
match &mut new {
Color::Srgba(x) => *x = x.darker(amount),
Color::LinearRgba(x) => *x = x.darker(amount),
Color::Hsla(x) => *x = x.darker(amount),
Color::Hsva(x) => *x = ChosenColorSpace::from(*x).darker(amount).into(),
Color::Hwba(x) => *x = ChosenColorSpace::from(*x).darker(amount).into(),
Color::Laba(x) => *x = x.darker(amount),
Color::Lcha(x) => *x = x.darker(amount),
Color::Oklaba(x) => *x = x.darker(amount),
Color::Oklcha(x) => *x = x.darker(amount),
Color::Xyza(x) => *x = x.darker(amount),
}
new
}
fn lighter(&self, amount: f32) -> Self {
let mut new = *self;
match &mut new {
Color::Srgba(x) => *x = x.lighter(amount),
Color::LinearRgba(x) => *x = x.lighter(amount),
Color::Hsla(x) => *x = x.lighter(amount),
Color::Hsva(x) => *x = ChosenColorSpace::from(*x).lighter(amount).into(),
Color::Hwba(x) => *x = ChosenColorSpace::from(*x).lighter(amount).into(),
Color::Laba(x) => *x = x.lighter(amount),
Color::Lcha(x) => *x = x.lighter(amount),
Color::Oklaba(x) => *x = x.lighter(amount),
Color::Oklcha(x) => *x = x.lighter(amount),
Color::Xyza(x) => *x = x.lighter(amount),
}
new
}
}
impl Hue for Color {
fn with_hue(&self, hue: f32) -> Self {
let mut new = *self;
match &mut new {
Color::Srgba(x) => *x = ChosenColorSpace::from(*x).with_hue(hue).into(),
Color::LinearRgba(x) => *x = ChosenColorSpace::from(*x).with_hue(hue).into(),
Color::Hsla(x) => *x = x.with_hue(hue),
Color::Hsva(x) => *x = x.with_hue(hue),
Color::Hwba(x) => *x = x.with_hue(hue),
Color::Laba(x) => *x = ChosenColorSpace::from(*x).with_hue(hue).into(),
Color::Lcha(x) => *x = x.with_hue(hue),
Color::Oklaba(x) => *x = ChosenColorSpace::from(*x).with_hue(hue).into(),
Color::Oklcha(x) => *x = x.with_hue(hue),
Color::Xyza(x) => *x = ChosenColorSpace::from(*x).with_hue(hue).into(),
}
new
}
fn hue(&self) -> f32 {
match self {
Color::Srgba(x) => ChosenColorSpace::from(*x).hue(),
Color::LinearRgba(x) => ChosenColorSpace::from(*x).hue(),
Color::Hsla(x) => x.hue(),
Color::Hsva(x) => x.hue(),
Color::Hwba(x) => x.hue(),
Color::Laba(x) => ChosenColorSpace::from(*x).hue(),
Color::Lcha(x) => x.hue(),
Color::Oklaba(x) => ChosenColorSpace::from(*x).hue(),
Color::Oklcha(x) => x.hue(),
Color::Xyza(x) => ChosenColorSpace::from(*x).hue(),
}
}
fn set_hue(&mut self, hue: f32) {
*self = self.with_hue(hue);
}
}
impl Saturation for Color {
fn with_saturation(&self, saturation: f32) -> Self {
let mut new = *self;
match &mut new {
Color::Srgba(x) => Hsla::from(*x).with_saturation(saturation).into(),
Color::LinearRgba(x) => Hsla::from(*x).with_saturation(saturation).into(),
Color::Hsla(x) => x.with_saturation(saturation).into(),
Color::Hsva(x) => x.with_saturation(saturation).into(),
Color::Hwba(x) => Hsla::from(*x).with_saturation(saturation).into(),
Color::Laba(x) => Hsla::from(*x).with_saturation(saturation).into(),
Color::Lcha(x) => Hsla::from(*x).with_saturation(saturation).into(),
Color::Oklaba(x) => Hsla::from(*x).with_saturation(saturation).into(),
Color::Oklcha(x) => Hsla::from(*x).with_saturation(saturation).into(),
Color::Xyza(x) => Hsla::from(*x).with_saturation(saturation).into(),
}
}
fn saturation(&self) -> f32 {
match self {
Color::Srgba(x) => Hsla::from(*x).saturation(),
Color::LinearRgba(x) => Hsla::from(*x).saturation(),
Color::Hsla(x) => x.saturation(),
Color::Hsva(x) => x.saturation(),
Color::Hwba(x) => Hsla::from(*x).saturation(),
Color::Laba(x) => Hsla::from(*x).saturation(),
Color::Lcha(x) => Hsla::from(*x).saturation(),
Color::Oklaba(x) => Hsla::from(*x).saturation(),
Color::Oklcha(x) => Hsla::from(*x).saturation(),
Color::Xyza(x) => Hsla::from(*x).saturation(),
}
}
fn set_saturation(&mut self, saturation: f32) {
*self = self.with_saturation(saturation);
}
}
impl Mix for Color {
fn mix(&self, other: &Self, factor: f32) -> Self {
let mut new = *self;
match &mut new {
Color::Srgba(x) => *x = x.mix(&(*other).into(), factor),
Color::LinearRgba(x) => *x = x.mix(&(*other).into(), factor),
Color::Hsla(x) => *x = x.mix(&(*other).into(), factor),
Color::Hsva(x) => *x = x.mix(&(*other).into(), factor),
Color::Hwba(x) => *x = x.mix(&(*other).into(), factor),
Color::Laba(x) => *x = x.mix(&(*other).into(), factor),
Color::Lcha(x) => *x = x.mix(&(*other).into(), factor),
Color::Oklaba(x) => *x = x.mix(&(*other).into(), factor),
Color::Oklcha(x) => *x = x.mix(&(*other).into(), factor),
Color::Xyza(x) => *x = x.mix(&(*other).into(), factor),
}
new
}
}
impl EuclideanDistance for Color {
fn distance_squared(&self, other: &Self) -> f32 {
match self {
Color::Srgba(x) => x.distance_squared(&(*other).into()),
Color::LinearRgba(x) => x.distance_squared(&(*other).into()),
Color::Hsla(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
Color::Hsva(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
Color::Hwba(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
Color::Laba(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
Color::Lcha(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
Color::Oklaba(x) => x.distance_squared(&(*other).into()),
Color::Oklcha(x) => x.distance_squared(&(*other).into()),
Color::Xyza(x) => ChosenColorSpace::from(*x).distance_squared(&(*other).into()),
}
}
}

View File

@@ -0,0 +1,15 @@
//! Module for calculating distance between two colors in the same color space.
use bevy_math::ops;
/// Calculate the distance between this and another color as if they were coordinates
/// in a Euclidean space. Alpha is not considered in the distance calculation.
pub trait EuclideanDistance: Sized {
/// Distance from `self` to `other`.
fn distance(&self, other: &Self) -> f32 {
ops::sqrt(self.distance_squared(other))
}
/// Distance squared from `self` to `other`.
fn distance_squared(&self, other: &Self) -> f32;
}

111
vendor/bevy_color/src/color_gradient.rs vendored Normal file
View File

@@ -0,0 +1,111 @@
use crate::Mix;
use alloc::vec::Vec;
use bevy_math::curve::{
cores::{EvenCore, EvenCoreError},
Curve, Interval,
};
/// A curve whose samples are defined by a collection of colors.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
pub struct ColorCurve<T> {
core: EvenCore<T>,
}
impl<T> ColorCurve<T>
where
T: Mix + Clone,
{
/// Create a new [`ColorCurve`] from a collection of [mixable] types. The domain of this curve
/// will always be `[0.0, len - 1]` where `len` is the amount of mixable objects in the
/// collection.
///
/// This fails if there's not at least two mixable things in the collection.
///
/// [mixable]: `Mix`
///
/// # Example
///
/// ```
/// # use bevy_color::palettes::basic::*;
/// # use bevy_color::Mix;
/// # use bevy_color::Srgba;
/// # use bevy_color::ColorCurve;
/// # use bevy_math::curve::Interval;
/// # use bevy_math::curve::Curve;
/// let broken = ColorCurve::new([RED]);
/// assert!(broken.is_err());
/// let gradient = ColorCurve::new([RED, GREEN, BLUE]);
/// assert!(gradient.is_ok());
/// assert_eq!(gradient.unwrap().domain(), Interval::new(0.0, 2.0).unwrap());
/// ```
pub fn new(colors: impl IntoIterator<Item = T>) -> Result<Self, EvenCoreError> {
let colors = colors.into_iter().collect::<Vec<_>>();
Interval::new(0.0, colors.len().saturating_sub(1) as f32)
.map_err(|_| EvenCoreError::NotEnoughSamples {
samples: colors.len(),
})
.and_then(|domain| EvenCore::new(domain, colors))
.map(|core| Self { core })
}
}
impl<T> Curve<T> for ColorCurve<T>
where
T: Mix + Clone,
{
#[inline]
fn domain(&self) -> Interval {
self.core.domain()
}
#[inline]
fn sample_clamped(&self, t: f32) -> T {
// `EvenCore::sample_with` clamps the input implicitly.
self.core.sample_with(t, T::mix)
}
#[inline]
fn sample_unchecked(&self, t: f32) -> T {
self.sample_clamped(t)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{palettes::basic, Srgba};
use bevy_math::curve::{Curve, CurveExt};
#[test]
fn test_color_curve() {
let broken = ColorCurve::new([basic::RED]);
assert!(broken.is_err());
let gradient = [basic::RED, basic::LIME, basic::BLUE];
let curve = ColorCurve::new(gradient).unwrap();
assert_eq!(curve.domain(), Interval::new(0.0, 2.0).unwrap());
let brighter_curve = curve.map(|c: Srgba| c.mix(&basic::WHITE, 0.5));
[
(-0.1, None),
(0.0, Some([1.0, 0.5, 0.5, 1.0])),
(0.5, Some([0.75, 0.75, 0.5, 1.0])),
(1.0, Some([0.5, 1.0, 0.5, 1.0])),
(1.5, Some([0.5, 0.75, 0.75, 1.0])),
(2.0, Some([0.5, 0.5, 1.0, 1.0])),
(2.1, None),
]
.map(|(t, maybe_rgba)| {
let maybe_srgba = maybe_rgba.map(|[r, g, b, a]| Srgba::new(r, g, b, a));
(t, maybe_srgba)
})
.into_iter()
.for_each(|(t, maybe_color)| {
assert_eq!(brighter_curve.sample(t), maybe_color);
});
}
}

211
vendor/bevy_color/src/color_ops.rs vendored Normal file
View File

@@ -0,0 +1,211 @@
use bevy_math::{ops, Vec3, Vec4};
/// Methods for changing the luminance of a color. Note that these methods are not
/// guaranteed to produce consistent results across color spaces,
/// but will be within a given space.
pub trait Luminance: Sized {
/// Return the luminance of this color (0.0 - 1.0).
fn luminance(&self) -> f32;
/// Return a new version of this color with the given luminance. The resulting color will
/// be clamped to the valid range for the color space; for some color spaces, clamping
/// may cause the hue or chroma to change.
fn with_luminance(&self, value: f32) -> Self;
/// Return a darker version of this color. The `amount` should be between 0.0 and 1.0.
/// The amount represents an absolute decrease in luminance, and is distributive:
/// `color.darker(a).darker(b) == color.darker(a + b)`. Colors are clamped to black
/// if the amount would cause them to go below black.
///
/// For a relative decrease in luminance, you can simply `mix()` with black.
fn darker(&self, amount: f32) -> Self;
/// Return a lighter version of this color. The `amount` should be between 0.0 and 1.0.
/// The amount represents an absolute increase in luminance, and is distributive:
/// `color.lighter(a).lighter(b) == color.lighter(a + b)`. Colors are clamped to white
/// if the amount would cause them to go above white.
///
/// For a relative increase in luminance, you can simply `mix()` with white.
fn lighter(&self, amount: f32) -> Self;
}
/// Linear interpolation of two colors within a given color space.
pub trait Mix: Sized {
/// Linearly interpolate between this and another color, by factor.
/// Factor should be between 0.0 and 1.0.
fn mix(&self, other: &Self, factor: f32) -> Self;
/// Linearly interpolate between this and another color, by factor, storing the result
/// in this color. Factor should be between 0.0 and 1.0.
fn mix_assign(&mut self, other: Self, factor: f32) {
*self = self.mix(&other, factor);
}
}
/// Trait for returning a grayscale color of a provided lightness.
pub trait Gray: Mix + Sized {
/// A pure black color.
const BLACK: Self;
/// A pure white color.
const WHITE: Self;
/// Returns a grey color with the provided lightness from (0.0 - 1.0). 0 is black, 1 is white.
fn gray(lightness: f32) -> Self {
Self::BLACK.mix(&Self::WHITE, lightness)
}
}
/// Methods for manipulating alpha values.
pub trait Alpha: Sized {
/// Return a new version of this color with the given alpha value.
fn with_alpha(&self, alpha: f32) -> Self;
/// Return a the alpha component of this color.
fn alpha(&self) -> f32;
/// Sets the alpha component of this color.
fn set_alpha(&mut self, alpha: f32);
/// Is the alpha component of this color less than or equal to 0.0?
fn is_fully_transparent(&self) -> bool {
self.alpha() <= 0.0
}
/// Is the alpha component of this color greater than or equal to 1.0?
fn is_fully_opaque(&self) -> bool {
self.alpha() >= 1.0
}
}
/// Trait for manipulating the hue of a color.
pub trait Hue: Sized {
/// Return a new version of this color with the hue channel set to the given value.
fn with_hue(&self, hue: f32) -> Self;
/// Return the hue of this color [0.0, 360.0].
fn hue(&self) -> f32;
/// Sets the hue of this color.
fn set_hue(&mut self, hue: f32);
/// Return a new version of this color with the hue channel rotated by the given degrees.
fn rotate_hue(&self, degrees: f32) -> Self {
let rotated_hue = ops::rem_euclid(self.hue() + degrees, 360.);
self.with_hue(rotated_hue)
}
}
/// Trait for manipulating the saturation of a color.
///
/// When working with color spaces that do not have native saturation components
/// the operations are performed in [`crate::Hsla`].
pub trait Saturation: Sized {
/// Return a new version of this color with the saturation channel set to the given value.
fn with_saturation(&self, saturation: f32) -> Self;
/// Return the saturation of this color [0.0, 1.0].
fn saturation(&self) -> f32;
/// Sets the saturation of this color.
fn set_saturation(&mut self, saturation: f32);
}
/// Trait with methods for converting colors to non-color types
pub trait ColorToComponents {
/// Convert to an f32 array
fn to_f32_array(self) -> [f32; 4];
/// Convert to an f32 array without the alpha value
fn to_f32_array_no_alpha(self) -> [f32; 3];
/// Convert to a Vec4
fn to_vec4(self) -> Vec4;
/// Convert to a Vec3
fn to_vec3(self) -> Vec3;
/// Convert from an f32 array
fn from_f32_array(color: [f32; 4]) -> Self;
/// Convert from an f32 array without the alpha value
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self;
/// Convert from a Vec4
fn from_vec4(color: Vec4) -> Self;
/// Convert from a Vec3
fn from_vec3(color: Vec3) -> Self;
}
/// Trait with methods for converting colors to packed non-color types
pub trait ColorToPacked {
/// Convert to [u8; 4] where that makes sense (Srgba is most relevant)
fn to_u8_array(self) -> [u8; 4];
/// Convert to [u8; 3] where that makes sense (Srgba is most relevant)
fn to_u8_array_no_alpha(self) -> [u8; 3];
/// Convert from [u8; 4] where that makes sense (Srgba is most relevant)
fn from_u8_array(color: [u8; 4]) -> Self;
/// Convert to [u8; 3] where that makes sense (Srgba is most relevant)
fn from_u8_array_no_alpha(color: [u8; 3]) -> Self;
}
/// Utility function for interpolating hue values. This ensures that the interpolation
/// takes the shortest path around the color wheel, and that the result is always between
/// 0 and 360.
pub(crate) fn lerp_hue(a: f32, b: f32, t: f32) -> f32 {
let diff = ops::rem_euclid(b - a + 180.0, 360.) - 180.;
ops::rem_euclid(a + diff * t, 360.)
}
#[cfg(test)]
mod tests {
use core::fmt::Debug;
use super::*;
use crate::{testing::assert_approx_eq, Hsla};
#[test]
fn test_rotate_hue() {
let hsla = Hsla::hsl(180.0, 1.0, 0.5);
assert_eq!(hsla.rotate_hue(90.0), Hsla::hsl(270.0, 1.0, 0.5));
assert_eq!(hsla.rotate_hue(-90.0), Hsla::hsl(90.0, 1.0, 0.5));
assert_eq!(hsla.rotate_hue(180.0), Hsla::hsl(0.0, 1.0, 0.5));
assert_eq!(hsla.rotate_hue(-180.0), Hsla::hsl(0.0, 1.0, 0.5));
assert_eq!(hsla.rotate_hue(0.0), hsla);
assert_eq!(hsla.rotate_hue(360.0), hsla);
assert_eq!(hsla.rotate_hue(-360.0), hsla);
}
#[test]
fn test_hue_wrap() {
assert_approx_eq!(lerp_hue(10., 20., 0.25), 12.5, 0.001);
assert_approx_eq!(lerp_hue(10., 20., 0.5), 15., 0.001);
assert_approx_eq!(lerp_hue(10., 20., 0.75), 17.5, 0.001);
assert_approx_eq!(lerp_hue(20., 10., 0.25), 17.5, 0.001);
assert_approx_eq!(lerp_hue(20., 10., 0.5), 15., 0.001);
assert_approx_eq!(lerp_hue(20., 10., 0.75), 12.5, 0.001);
assert_approx_eq!(lerp_hue(10., 350., 0.25), 5., 0.001);
assert_approx_eq!(lerp_hue(10., 350., 0.5), 0., 0.001);
assert_approx_eq!(lerp_hue(10., 350., 0.75), 355., 0.001);
assert_approx_eq!(lerp_hue(350., 10., 0.25), 355., 0.001);
assert_approx_eq!(lerp_hue(350., 10., 0.5), 0., 0.001);
assert_approx_eq!(lerp_hue(350., 10., 0.75), 5., 0.001);
}
fn verify_gray<Col>()
where
Col: Gray + Debug + PartialEq,
{
assert_eq!(Col::gray(0.), Col::BLACK);
assert_eq!(Col::gray(1.), Col::WHITE);
}
#[test]
fn test_gray() {
verify_gray::<Hsla>();
verify_gray::<crate::Hsva>();
verify_gray::<crate::Hwba>();
verify_gray::<crate::Laba>();
verify_gray::<crate::Lcha>();
verify_gray::<crate::LinearRgba>();
verify_gray::<crate::Oklaba>();
verify_gray::<crate::Oklcha>();
verify_gray::<crate::Xyza>();
}
}

46
vendor/bevy_color/src/color_range.rs vendored Normal file
View File

@@ -0,0 +1,46 @@
use core::ops::Range;
use crate::Mix;
/// Represents a range of colors that can be linearly interpolated, defined by a start and
/// end point which must be in the same color space. It works for any color type that
/// implements [`Mix`].
///
/// This is useful for defining gradients or animated color transitions.
pub trait ColorRange<T: Mix> {
/// Get the color value at the given interpolation factor, which should be between 0.0 (start)
/// and 1.0 (end).
fn at(&self, factor: f32) -> T;
}
impl<T: Mix> ColorRange<T> for Range<T> {
fn at(&self, factor: f32) -> T {
self.start.mix(&self.end, factor.clamp(0.0, 1.0))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{palettes::basic, LinearRgba, Srgba};
#[test]
fn test_color_range() {
let range = basic::RED..basic::BLUE;
assert_eq!(range.at(-0.5), basic::RED);
assert_eq!(range.at(0.0), basic::RED);
assert_eq!(range.at(0.5), Srgba::new(0.5, 0.0, 0.5, 1.0));
assert_eq!(range.at(1.0), basic::BLUE);
assert_eq!(range.at(1.5), basic::BLUE);
let lred: LinearRgba = basic::RED.into();
let lblue: LinearRgba = basic::BLUE.into();
let range = lred..lblue;
assert_eq!(range.at(-0.5), lred);
assert_eq!(range.at(0.0), lred);
assert_eq!(range.at(0.5), LinearRgba::new(0.5, 0.0, 0.5, 1.0));
assert_eq!(range.at(1.0), lblue);
assert_eq!(range.at(1.5), lblue);
}
}

455
vendor/bevy_color/src/hsla.rs vendored Normal file
View File

@@ -0,0 +1,455 @@
use crate::{
Alpha, ColorToComponents, Gray, Hsva, Hue, Hwba, Lcha, LinearRgba, Luminance, Mix, Saturation,
Srgba, StandardColor, Xyza,
};
use bevy_math::{Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
/// Color in Hue-Saturation-Lightness (HSL) color space with alpha.
/// Further information on this color model can be found on [Wikipedia](https://en.wikipedia.org/wiki/HSL_and_HSV).
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct Hsla {
/// The hue channel. [0.0, 360.0]
pub hue: f32,
/// The saturation channel. [0.0, 1.0]
pub saturation: f32,
/// The lightness channel. [0.0, 1.0]
pub lightness: f32,
/// The alpha channel. [0.0, 1.0]
pub alpha: f32,
}
impl StandardColor for Hsla {}
impl Hsla {
/// Construct a new [`Hsla`] color from components.
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `saturation` - Saturation channel. [0.0, 1.0]
/// * `lightness` - Lightness channel. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn new(hue: f32, saturation: f32, lightness: f32, alpha: f32) -> Self {
Self {
hue,
saturation,
lightness,
alpha,
}
}
/// Construct a new [`Hsla`] color from (h, s, l) components, with the default alpha (1.0).
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `saturation` - Saturation channel. [0.0, 1.0]
/// * `lightness` - Lightness channel. [0.0, 1.0]
pub const fn hsl(hue: f32, saturation: f32, lightness: f32) -> Self {
Self::new(hue, saturation, lightness, 1.0)
}
/// Return a copy of this color with the saturation channel set to the given value.
pub const fn with_saturation(self, saturation: f32) -> Self {
Self { saturation, ..self }
}
/// Return a copy of this color with the lightness channel set to the given value.
pub const fn with_lightness(self, lightness: f32) -> Self {
Self { lightness, ..self }
}
/// Generate a deterministic but [quasi-randomly distributed](https://en.wikipedia.org/wiki/Low-discrepancy_sequence)
/// color from a provided `index`.
///
/// This can be helpful for generating debug colors.
///
/// # Examples
///
/// ```rust
/// # use bevy_color::Hsla;
/// // Unique color for an entity
/// # let entity_index = 123;
/// // let entity_index = entity.index();
/// let color = Hsla::sequential_dispersed(entity_index);
///
/// // Palette with 5 distinct hues
/// let palette = (0..5).map(Hsla::sequential_dispersed).collect::<Vec<_>>();
/// ```
pub fn sequential_dispersed(index: u32) -> Self {
const FRAC_U32MAX_GOLDEN_RATIO: u32 = 2654435769; // (u32::MAX / Φ) rounded up
const RATIO_360: f32 = 360.0 / u32::MAX as f32;
// from https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/
//
// Map a sequence of integers (eg: 154, 155, 156, 157, 158) into the [0.0..1.0] range,
// so that the closer the numbers are, the larger the difference of their image.
let hue = index.wrapping_mul(FRAC_U32MAX_GOLDEN_RATIO) as f32 * RATIO_360;
Self::hsl(hue, 1., 0.5)
}
}
impl Default for Hsla {
fn default() -> Self {
Self::new(0., 0., 1., 1.)
}
}
impl Mix for Hsla {
#[inline]
fn mix(&self, other: &Self, factor: f32) -> Self {
let n_factor = 1.0 - factor;
Self {
hue: crate::color_ops::lerp_hue(self.hue, other.hue, factor),
saturation: self.saturation * n_factor + other.saturation * factor,
lightness: self.lightness * n_factor + other.lightness * factor,
alpha: self.alpha * n_factor + other.alpha * factor,
}
}
}
impl Gray for Hsla {
const BLACK: Self = Self::new(0., 0., 0., 1.);
const WHITE: Self = Self::new(0., 0., 1., 1.);
}
impl Alpha for Hsla {
#[inline]
fn with_alpha(&self, alpha: f32) -> Self {
Self { alpha, ..*self }
}
#[inline]
fn alpha(&self) -> f32 {
self.alpha
}
#[inline]
fn set_alpha(&mut self, alpha: f32) {
self.alpha = alpha;
}
}
impl Hue for Hsla {
#[inline]
fn with_hue(&self, hue: f32) -> Self {
Self { hue, ..*self }
}
#[inline]
fn hue(&self) -> f32 {
self.hue
}
#[inline]
fn set_hue(&mut self, hue: f32) {
self.hue = hue;
}
}
impl Saturation for Hsla {
#[inline]
fn with_saturation(&self, saturation: f32) -> Self {
Self {
saturation,
..*self
}
}
#[inline]
fn saturation(&self) -> f32 {
self.saturation
}
#[inline]
fn set_saturation(&mut self, saturation: f32) {
self.saturation = saturation;
}
}
impl Luminance for Hsla {
#[inline]
fn with_luminance(&self, lightness: f32) -> Self {
Self { lightness, ..*self }
}
fn luminance(&self) -> f32 {
self.lightness
}
fn darker(&self, amount: f32) -> Self {
Self {
lightness: (self.lightness - amount).clamp(0., 1.),
..*self
}
}
fn lighter(&self, amount: f32) -> Self {
Self {
lightness: (self.lightness + amount).min(1.),
..*self
}
}
}
impl ColorToComponents for Hsla {
fn to_f32_array(self) -> [f32; 4] {
[self.hue, self.saturation, self.lightness, self.alpha]
}
fn to_f32_array_no_alpha(self) -> [f32; 3] {
[self.hue, self.saturation, self.lightness]
}
fn to_vec4(self) -> Vec4 {
Vec4::new(self.hue, self.saturation, self.lightness, self.alpha)
}
fn to_vec3(self) -> Vec3 {
Vec3::new(self.hue, self.saturation, self.lightness)
}
fn from_f32_array(color: [f32; 4]) -> Self {
Self {
hue: color[0],
saturation: color[1],
lightness: color[2],
alpha: color[3],
}
}
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self {
Self {
hue: color[0],
saturation: color[1],
lightness: color[2],
alpha: 1.0,
}
}
fn from_vec4(color: Vec4) -> Self {
Self {
hue: color[0],
saturation: color[1],
lightness: color[2],
alpha: color[3],
}
}
fn from_vec3(color: Vec3) -> Self {
Self {
hue: color[0],
saturation: color[1],
lightness: color[2],
alpha: 1.0,
}
}
}
impl From<Hsla> for Hsva {
fn from(
Hsla {
hue,
saturation,
lightness,
alpha,
}: Hsla,
) -> Self {
// Based on https://en.wikipedia.org/wiki/HSL_and_HSV#HSL_to_HSV
let value = lightness + saturation * lightness.min(1. - lightness);
let saturation = if value == 0. {
0.
} else {
2. * (1. - (lightness / value))
};
Hsva::new(hue, saturation, value, alpha)
}
}
impl From<Hsva> for Hsla {
fn from(
Hsva {
hue,
saturation,
value,
alpha,
}: Hsva,
) -> Self {
// Based on https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_HSL
let lightness = value * (1. - saturation / 2.);
let saturation = if lightness == 0. || lightness == 1. {
0.
} else {
(value - lightness) / lightness.min(1. - lightness)
};
Hsla::new(hue, saturation, lightness, alpha)
}
}
// Derived Conversions
impl From<Hwba> for Hsla {
fn from(value: Hwba) -> Self {
Hsva::from(value).into()
}
}
impl From<Hsla> for Hwba {
fn from(value: Hsla) -> Self {
Hsva::from(value).into()
}
}
impl From<Srgba> for Hsla {
fn from(value: Srgba) -> Self {
Hsva::from(value).into()
}
}
impl From<Hsla> for Srgba {
fn from(value: Hsla) -> Self {
Hsva::from(value).into()
}
}
impl From<LinearRgba> for Hsla {
fn from(value: LinearRgba) -> Self {
Hsva::from(value).into()
}
}
impl From<Hsla> for LinearRgba {
fn from(value: Hsla) -> Self {
Hsva::from(value).into()
}
}
impl From<Lcha> for Hsla {
fn from(value: Lcha) -> Self {
Hsva::from(value).into()
}
}
impl From<Hsla> for Lcha {
fn from(value: Hsla) -> Self {
Hsva::from(value).into()
}
}
impl From<Xyza> for Hsla {
fn from(value: Xyza) -> Self {
Hsva::from(value).into()
}
}
impl From<Hsla> for Xyza {
fn from(value: Hsla) -> Self {
Hsva::from(value).into()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
color_difference::EuclideanDistance, test_colors::TEST_COLORS, testing::assert_approx_eq,
};
#[test]
fn test_to_from_srgba() {
let hsla = Hsla::new(0.5, 0.5, 0.5, 1.0);
let srgba: Srgba = hsla.into();
let hsla2: Hsla = srgba.into();
assert_approx_eq!(hsla.hue, hsla2.hue, 0.001);
assert_approx_eq!(hsla.saturation, hsla2.saturation, 0.001);
assert_approx_eq!(hsla.lightness, hsla2.lightness, 0.001);
assert_approx_eq!(hsla.alpha, hsla2.alpha, 0.001);
}
#[test]
fn test_to_from_srgba_2() {
for color in TEST_COLORS.iter() {
let rgb2: Srgba = (color.hsl).into();
let hsl2: Hsla = (color.rgb).into();
assert!(
color.rgb.distance(&rgb2) < 0.000001,
"{}: {:?} != {:?}",
color.name,
color.rgb,
rgb2
);
assert_approx_eq!(color.hsl.hue, hsl2.hue, 0.001);
assert_approx_eq!(color.hsl.saturation, hsl2.saturation, 0.001);
assert_approx_eq!(color.hsl.lightness, hsl2.lightness, 0.001);
assert_approx_eq!(color.hsl.alpha, hsl2.alpha, 0.001);
}
}
#[test]
fn test_to_from_linear() {
let hsla = Hsla::new(0.5, 0.5, 0.5, 1.0);
let linear: LinearRgba = hsla.into();
let hsla2: Hsla = linear.into();
assert_approx_eq!(hsla.hue, hsla2.hue, 0.001);
assert_approx_eq!(hsla.saturation, hsla2.saturation, 0.001);
assert_approx_eq!(hsla.lightness, hsla2.lightness, 0.001);
assert_approx_eq!(hsla.alpha, hsla2.alpha, 0.001);
}
#[test]
fn test_mix_wrap() {
let hsla0 = Hsla::new(10., 0.5, 0.5, 1.0);
let hsla1 = Hsla::new(20., 0.5, 0.5, 1.0);
let hsla2 = Hsla::new(350., 0.5, 0.5, 1.0);
assert_approx_eq!(hsla0.mix(&hsla1, 0.25).hue, 12.5, 0.001);
assert_approx_eq!(hsla0.mix(&hsla1, 0.5).hue, 15., 0.001);
assert_approx_eq!(hsla0.mix(&hsla1, 0.75).hue, 17.5, 0.001);
assert_approx_eq!(hsla1.mix(&hsla0, 0.25).hue, 17.5, 0.001);
assert_approx_eq!(hsla1.mix(&hsla0, 0.5).hue, 15., 0.001);
assert_approx_eq!(hsla1.mix(&hsla0, 0.75).hue, 12.5, 0.001);
assert_approx_eq!(hsla0.mix(&hsla2, 0.25).hue, 5., 0.001);
assert_approx_eq!(hsla0.mix(&hsla2, 0.5).hue, 0., 0.001);
assert_approx_eq!(hsla0.mix(&hsla2, 0.75).hue, 355., 0.001);
assert_approx_eq!(hsla2.mix(&hsla0, 0.25).hue, 355., 0.001);
assert_approx_eq!(hsla2.mix(&hsla0, 0.5).hue, 0., 0.001);
assert_approx_eq!(hsla2.mix(&hsla0, 0.75).hue, 5., 0.001);
}
#[test]
fn test_from_index() {
let references = [
Hsla::hsl(0.0, 1., 0.5),
Hsla::hsl(222.49225, 1., 0.5),
Hsla::hsl(84.984474, 1., 0.5),
Hsla::hsl(307.4767, 1., 0.5),
Hsla::hsl(169.96895, 1., 0.5),
];
for (index, reference) in references.into_iter().enumerate() {
let color = Hsla::sequential_dispersed(index as u32);
assert_approx_eq!(color.hue, reference.hue, 0.001);
}
}
}

335
vendor/bevy_color/src/hsva.rs vendored Normal file
View File

@@ -0,0 +1,335 @@
use crate::{
Alpha, ColorToComponents, Gray, Hue, Hwba, Lcha, LinearRgba, Mix, Saturation, Srgba,
StandardColor, Xyza,
};
use bevy_math::{Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
/// Color in Hue-Saturation-Value (HSV) color space with alpha.
/// Further information on this color model can be found on [Wikipedia](https://en.wikipedia.org/wiki/HSL_and_HSV).
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct Hsva {
/// The hue channel. [0.0, 360.0]
pub hue: f32,
/// The saturation channel. [0.0, 1.0]
pub saturation: f32,
/// The value channel. [0.0, 1.0]
pub value: f32,
/// The alpha channel. [0.0, 1.0]
pub alpha: f32,
}
impl StandardColor for Hsva {}
impl Hsva {
/// Construct a new [`Hsva`] color from components.
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `saturation` - Saturation channel. [0.0, 1.0]
/// * `value` - Value channel. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn new(hue: f32, saturation: f32, value: f32, alpha: f32) -> Self {
Self {
hue,
saturation,
value,
alpha,
}
}
/// Construct a new [`Hsva`] color from (h, s, v) components, with the default alpha (1.0).
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `saturation` - Saturation channel. [0.0, 1.0]
/// * `value` - Value channel. [0.0, 1.0]
pub const fn hsv(hue: f32, saturation: f32, value: f32) -> Self {
Self::new(hue, saturation, value, 1.0)
}
/// Return a copy of this color with the saturation channel set to the given value.
pub const fn with_saturation(self, saturation: f32) -> Self {
Self { saturation, ..self }
}
/// Return a copy of this color with the value channel set to the given value.
pub const fn with_value(self, value: f32) -> Self {
Self { value, ..self }
}
}
impl Default for Hsva {
fn default() -> Self {
Self::new(0., 0., 1., 1.)
}
}
impl Mix for Hsva {
#[inline]
fn mix(&self, other: &Self, factor: f32) -> Self {
let n_factor = 1.0 - factor;
Self {
hue: crate::color_ops::lerp_hue(self.hue, other.hue, factor),
saturation: self.saturation * n_factor + other.saturation * factor,
value: self.value * n_factor + other.value * factor,
alpha: self.alpha * n_factor + other.alpha * factor,
}
}
}
impl Gray for Hsva {
const BLACK: Self = Self::new(0., 0., 0., 1.);
const WHITE: Self = Self::new(0., 0., 1., 1.);
}
impl Alpha for Hsva {
#[inline]
fn with_alpha(&self, alpha: f32) -> Self {
Self { alpha, ..*self }
}
#[inline]
fn alpha(&self) -> f32 {
self.alpha
}
#[inline]
fn set_alpha(&mut self, alpha: f32) {
self.alpha = alpha;
}
}
impl Hue for Hsva {
#[inline]
fn with_hue(&self, hue: f32) -> Self {
Self { hue, ..*self }
}
#[inline]
fn hue(&self) -> f32 {
self.hue
}
#[inline]
fn set_hue(&mut self, hue: f32) {
self.hue = hue;
}
}
impl Saturation for Hsva {
#[inline]
fn with_saturation(&self, saturation: f32) -> Self {
Self {
saturation,
..*self
}
}
#[inline]
fn saturation(&self) -> f32 {
self.saturation
}
#[inline]
fn set_saturation(&mut self, saturation: f32) {
self.saturation = saturation;
}
}
impl From<Hsva> for Hwba {
fn from(
Hsva {
hue,
saturation,
value,
alpha,
}: Hsva,
) -> Self {
// Based on https://en.wikipedia.org/wiki/HWB_color_model#Conversion
let whiteness = (1. - saturation) * value;
let blackness = 1. - value;
Hwba::new(hue, whiteness, blackness, alpha)
}
}
impl From<Hwba> for Hsva {
fn from(
Hwba {
hue,
whiteness,
blackness,
alpha,
}: Hwba,
) -> Self {
// Based on https://en.wikipedia.org/wiki/HWB_color_model#Conversion
let value = 1. - blackness;
let saturation = if value != 0. {
1. - (whiteness / value)
} else {
0.
};
Hsva::new(hue, saturation, value, alpha)
}
}
impl ColorToComponents for Hsva {
fn to_f32_array(self) -> [f32; 4] {
[self.hue, self.saturation, self.value, self.alpha]
}
fn to_f32_array_no_alpha(self) -> [f32; 3] {
[self.hue, self.saturation, self.value]
}
fn to_vec4(self) -> Vec4 {
Vec4::new(self.hue, self.saturation, self.value, self.alpha)
}
fn to_vec3(self) -> Vec3 {
Vec3::new(self.hue, self.saturation, self.value)
}
fn from_f32_array(color: [f32; 4]) -> Self {
Self {
hue: color[0],
saturation: color[1],
value: color[2],
alpha: color[3],
}
}
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self {
Self {
hue: color[0],
saturation: color[1],
value: color[2],
alpha: 1.0,
}
}
fn from_vec4(color: Vec4) -> Self {
Self {
hue: color[0],
saturation: color[1],
value: color[2],
alpha: color[3],
}
}
fn from_vec3(color: Vec3) -> Self {
Self {
hue: color[0],
saturation: color[1],
value: color[2],
alpha: 1.0,
}
}
}
// Derived Conversions
impl From<Srgba> for Hsva {
fn from(value: Srgba) -> Self {
Hwba::from(value).into()
}
}
impl From<Hsva> for Srgba {
fn from(value: Hsva) -> Self {
Hwba::from(value).into()
}
}
impl From<LinearRgba> for Hsva {
fn from(value: LinearRgba) -> Self {
Hwba::from(value).into()
}
}
impl From<Hsva> for LinearRgba {
fn from(value: Hsva) -> Self {
Hwba::from(value).into()
}
}
impl From<Lcha> for Hsva {
fn from(value: Lcha) -> Self {
Hwba::from(value).into()
}
}
impl From<Hsva> for Lcha {
fn from(value: Hsva) -> Self {
Hwba::from(value).into()
}
}
impl From<Xyza> for Hsva {
fn from(value: Xyza) -> Self {
Hwba::from(value).into()
}
}
impl From<Hsva> for Xyza {
fn from(value: Hsva) -> Self {
Hwba::from(value).into()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
color_difference::EuclideanDistance, test_colors::TEST_COLORS, testing::assert_approx_eq,
};
#[test]
fn test_to_from_srgba() {
let hsva = Hsva::new(180., 0.5, 0.5, 1.0);
let srgba: Srgba = hsva.into();
let hsva2: Hsva = srgba.into();
assert_approx_eq!(hsva.hue, hsva2.hue, 0.001);
assert_approx_eq!(hsva.saturation, hsva2.saturation, 0.001);
assert_approx_eq!(hsva.value, hsva2.value, 0.001);
assert_approx_eq!(hsva.alpha, hsva2.alpha, 0.001);
}
#[test]
fn test_to_from_srgba_2() {
for color in TEST_COLORS.iter() {
let rgb2: Srgba = (color.hsv).into();
let hsv2: Hsva = (color.rgb).into();
assert!(
color.rgb.distance(&rgb2) < 0.00001,
"{}: {:?} != {:?}",
color.name,
color.rgb,
rgb2
);
assert_approx_eq!(color.hsv.hue, hsv2.hue, 0.001);
assert_approx_eq!(color.hsv.saturation, hsv2.saturation, 0.001);
assert_approx_eq!(color.hsv.value, hsv2.value, 0.001);
assert_approx_eq!(color.hsv.alpha, hsv2.alpha, 0.001);
}
}
}

343
vendor/bevy_color/src/hwba.rs vendored Normal file
View File

@@ -0,0 +1,343 @@
//! Implementation of the Hue-Whiteness-Blackness (HWB) color model as described
//! in [_HWB - A More Intuitive Hue-Based Color Model_] by _Smith et al_.
//!
//! [_HWB - A More Intuitive Hue-Based Color Model_]: https://web.archive.org/web/20240226005220/http://alvyray.com/Papers/CG/HWB_JGTv208.pdf
use crate::{
Alpha, ColorToComponents, Gray, Hue, Lcha, LinearRgba, Mix, Srgba, StandardColor, Xyza,
};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
/// Color in Hue-Whiteness-Blackness (HWB) color space with alpha.
/// Further information on this color model can be found on [Wikipedia](https://en.wikipedia.org/wiki/HWB_color_model).
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct Hwba {
/// The hue channel. [0.0, 360.0]
pub hue: f32,
/// The whiteness channel. [0.0, 1.0]
pub whiteness: f32,
/// The blackness channel. [0.0, 1.0]
pub blackness: f32,
/// The alpha channel. [0.0, 1.0]
pub alpha: f32,
}
impl StandardColor for Hwba {}
impl Hwba {
/// Construct a new [`Hwba`] color from components.
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `whiteness` - Whiteness channel. [0.0, 1.0]
/// * `blackness` - Blackness channel. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn new(hue: f32, whiteness: f32, blackness: f32, alpha: f32) -> Self {
Self {
hue,
whiteness,
blackness,
alpha,
}
}
/// Construct a new [`Hwba`] color from (h, s, l) components, with the default alpha (1.0).
///
/// # Arguments
///
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `whiteness` - Whiteness channel. [0.0, 1.0]
/// * `blackness` - Blackness channel. [0.0, 1.0]
pub const fn hwb(hue: f32, whiteness: f32, blackness: f32) -> Self {
Self::new(hue, whiteness, blackness, 1.0)
}
/// Return a copy of this color with the whiteness channel set to the given value.
pub const fn with_whiteness(self, whiteness: f32) -> Self {
Self { whiteness, ..self }
}
/// Return a copy of this color with the blackness channel set to the given value.
pub const fn with_blackness(self, blackness: f32) -> Self {
Self { blackness, ..self }
}
}
impl Default for Hwba {
fn default() -> Self {
Self::new(0., 0., 1., 1.)
}
}
impl Mix for Hwba {
#[inline]
fn mix(&self, other: &Self, factor: f32) -> Self {
let n_factor = 1.0 - factor;
Self {
hue: crate::color_ops::lerp_hue(self.hue, other.hue, factor),
whiteness: self.whiteness * n_factor + other.whiteness * factor,
blackness: self.blackness * n_factor + other.blackness * factor,
alpha: self.alpha * n_factor + other.alpha * factor,
}
}
}
impl Gray for Hwba {
const BLACK: Self = Self::new(0., 0., 1., 1.);
const WHITE: Self = Self::new(0., 1., 0., 1.);
}
impl Alpha for Hwba {
#[inline]
fn with_alpha(&self, alpha: f32) -> Self {
Self { alpha, ..*self }
}
#[inline]
fn alpha(&self) -> f32 {
self.alpha
}
#[inline]
fn set_alpha(&mut self, alpha: f32) {
self.alpha = alpha;
}
}
impl Hue for Hwba {
#[inline]
fn with_hue(&self, hue: f32) -> Self {
Self { hue, ..*self }
}
#[inline]
fn hue(&self) -> f32 {
self.hue
}
#[inline]
fn set_hue(&mut self, hue: f32) {
self.hue = hue;
}
}
impl ColorToComponents for Hwba {
fn to_f32_array(self) -> [f32; 4] {
[self.hue, self.whiteness, self.blackness, self.alpha]
}
fn to_f32_array_no_alpha(self) -> [f32; 3] {
[self.hue, self.whiteness, self.blackness]
}
fn to_vec4(self) -> Vec4 {
Vec4::new(self.hue, self.whiteness, self.blackness, self.alpha)
}
fn to_vec3(self) -> Vec3 {
Vec3::new(self.hue, self.whiteness, self.blackness)
}
fn from_f32_array(color: [f32; 4]) -> Self {
Self {
hue: color[0],
whiteness: color[1],
blackness: color[2],
alpha: color[3],
}
}
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self {
Self {
hue: color[0],
whiteness: color[1],
blackness: color[2],
alpha: 1.0,
}
}
fn from_vec4(color: Vec4) -> Self {
Self {
hue: color[0],
whiteness: color[1],
blackness: color[2],
alpha: color[3],
}
}
fn from_vec3(color: Vec3) -> Self {
Self {
hue: color[0],
whiteness: color[1],
blackness: color[2],
alpha: 1.0,
}
}
}
impl From<Srgba> for Hwba {
fn from(
Srgba {
red,
green,
blue,
alpha,
}: Srgba,
) -> Self {
// Based on "HWB - A More Intuitive Hue-Based Color Model" Appendix B
let x_max = 0f32.max(red).max(green).max(blue);
let x_min = 1f32.min(red).min(green).min(blue);
let chroma = x_max - x_min;
let hue = if chroma == 0.0 {
0.0
} else if red == x_max {
60.0 * (green - blue) / chroma
} else if green == x_max {
60.0 * (2.0 + (blue - red) / chroma)
} else {
60.0 * (4.0 + (red - green) / chroma)
};
let hue = if hue < 0.0 { 360.0 + hue } else { hue };
let whiteness = x_min;
let blackness = 1.0 - x_max;
Hwba {
hue,
whiteness,
blackness,
alpha,
}
}
}
impl From<Hwba> for Srgba {
fn from(
Hwba {
hue,
whiteness,
blackness,
alpha,
}: Hwba,
) -> Self {
// Based on "HWB - A More Intuitive Hue-Based Color Model" Appendix B
let w = whiteness;
let v = 1. - blackness;
let h = (hue % 360.) / 60.;
let i = ops::floor(h);
let f = h - i;
let i = i as u8;
let f = if i % 2 == 0 { f } else { 1. - f };
let n = w + f * (v - w);
let (red, green, blue) = match i {
0 => (v, n, w),
1 => (n, v, w),
2 => (w, v, n),
3 => (w, n, v),
4 => (n, w, v),
5 => (v, w, n),
_ => unreachable!("i is bounded in [0, 6)"),
};
Srgba::new(red, green, blue, alpha)
}
}
// Derived Conversions
impl From<LinearRgba> for Hwba {
fn from(value: LinearRgba) -> Self {
Srgba::from(value).into()
}
}
impl From<Hwba> for LinearRgba {
fn from(value: Hwba) -> Self {
Srgba::from(value).into()
}
}
impl From<Lcha> for Hwba {
fn from(value: Lcha) -> Self {
Srgba::from(value).into()
}
}
impl From<Hwba> for Lcha {
fn from(value: Hwba) -> Self {
Srgba::from(value).into()
}
}
impl From<Xyza> for Hwba {
fn from(value: Xyza) -> Self {
Srgba::from(value).into()
}
}
impl From<Hwba> for Xyza {
fn from(value: Hwba) -> Self {
Srgba::from(value).into()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
color_difference::EuclideanDistance, test_colors::TEST_COLORS, testing::assert_approx_eq,
};
#[test]
fn test_to_from_srgba() {
let hwba = Hwba::new(0.0, 0.5, 0.5, 1.0);
let srgba: Srgba = hwba.into();
let hwba2: Hwba = srgba.into();
assert_approx_eq!(hwba.hue, hwba2.hue, 0.001);
assert_approx_eq!(hwba.whiteness, hwba2.whiteness, 0.001);
assert_approx_eq!(hwba.blackness, hwba2.blackness, 0.001);
assert_approx_eq!(hwba.alpha, hwba2.alpha, 0.001);
}
#[test]
fn test_to_from_srgba_2() {
for color in TEST_COLORS.iter() {
let rgb2: Srgba = (color.hwb).into();
let hwb2: Hwba = (color.rgb).into();
assert!(
color.rgb.distance(&rgb2) < 0.00001,
"{}: {:?} != {:?}",
color.name,
color.rgb,
rgb2
);
assert_approx_eq!(color.hwb.hue, hwb2.hue, 0.001);
assert_approx_eq!(color.hwb.whiteness, hwb2.whiteness, 0.001);
assert_approx_eq!(color.hwb.blackness, hwb2.blackness, 0.001);
assert_approx_eq!(color.hwb.alpha, hwb2.alpha, 0.001);
}
}
}

427
vendor/bevy_color/src/laba.rs vendored Normal file
View File

@@ -0,0 +1,427 @@
use crate::{
impl_componentwise_vector_space, Alpha, ColorToComponents, Gray, Hsla, Hsva, Hwba, LinearRgba,
Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza,
};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
/// Color in LAB color space, with alpha
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct Laba {
/// The lightness channel. [0.0, 1.5]
pub lightness: f32,
/// The a axis. [-1.5, 1.5]
pub a: f32,
/// The b axis. [-1.5, 1.5]
pub b: f32,
/// The alpha channel. [0.0, 1.0]
pub alpha: f32,
}
impl StandardColor for Laba {}
impl_componentwise_vector_space!(Laba, [lightness, a, b, alpha]);
impl Laba {
/// Construct a new [`Laba`] color from components.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.5]
/// * `a` - a axis. [-1.5, 1.5]
/// * `b` - b axis. [-1.5, 1.5]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn new(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
Self {
lightness,
a,
b,
alpha,
}
}
/// Construct a new [`Laba`] color from (l, a, b) components, with the default alpha (1.0).
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.5]
/// * `a` - a axis. [-1.5, 1.5]
/// * `b` - b axis. [-1.5, 1.5]
pub const fn lab(lightness: f32, a: f32, b: f32) -> Self {
Self {
lightness,
a,
b,
alpha: 1.0,
}
}
/// Return a copy of this color with the lightness channel set to the given value.
pub const fn with_lightness(self, lightness: f32) -> Self {
Self { lightness, ..self }
}
/// CIE Epsilon Constant
///
/// See [Continuity (16) (17)](http://brucelindbloom.com/index.html?LContinuity.html)
pub const CIE_EPSILON: f32 = 216.0 / 24389.0;
/// CIE Kappa Constant
///
/// See [Continuity (16) (17)](http://brucelindbloom.com/index.html?LContinuity.html)
pub const CIE_KAPPA: f32 = 24389.0 / 27.0;
}
impl Default for Laba {
fn default() -> Self {
Self::new(1., 0., 0., 1.)
}
}
impl Mix for Laba {
#[inline]
fn mix(&self, other: &Self, factor: f32) -> Self {
let n_factor = 1.0 - factor;
Self {
lightness: self.lightness * n_factor + other.lightness * factor,
a: self.a * n_factor + other.a * factor,
b: self.b * n_factor + other.b * factor,
alpha: self.alpha * n_factor + other.alpha * factor,
}
}
}
impl Gray for Laba {
const BLACK: Self = Self::new(0., 0., 0., 1.);
const WHITE: Self = Self::new(1., 0., 0., 1.);
}
impl Alpha for Laba {
#[inline]
fn with_alpha(&self, alpha: f32) -> Self {
Self { alpha, ..*self }
}
#[inline]
fn alpha(&self) -> f32 {
self.alpha
}
#[inline]
fn set_alpha(&mut self, alpha: f32) {
self.alpha = alpha;
}
}
impl Luminance for Laba {
#[inline]
fn with_luminance(&self, lightness: f32) -> Self {
Self { lightness, ..*self }
}
fn luminance(&self) -> f32 {
self.lightness
}
fn darker(&self, amount: f32) -> Self {
Self::new(
(self.lightness - amount).max(0.),
self.a,
self.b,
self.alpha,
)
}
fn lighter(&self, amount: f32) -> Self {
Self::new(
(self.lightness + amount).min(1.),
self.a,
self.b,
self.alpha,
)
}
}
impl ColorToComponents for Laba {
fn to_f32_array(self) -> [f32; 4] {
[self.lightness, self.a, self.b, self.alpha]
}
fn to_f32_array_no_alpha(self) -> [f32; 3] {
[self.lightness, self.a, self.b]
}
fn to_vec4(self) -> Vec4 {
Vec4::new(self.lightness, self.a, self.b, self.alpha)
}
fn to_vec3(self) -> Vec3 {
Vec3::new(self.lightness, self.a, self.b)
}
fn from_f32_array(color: [f32; 4]) -> Self {
Self {
lightness: color[0],
a: color[1],
b: color[2],
alpha: color[3],
}
}
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self {
Self {
lightness: color[0],
a: color[1],
b: color[2],
alpha: 1.0,
}
}
fn from_vec4(color: Vec4) -> Self {
Self {
lightness: color[0],
a: color[1],
b: color[2],
alpha: color[3],
}
}
fn from_vec3(color: Vec3) -> Self {
Self {
lightness: color[0],
a: color[1],
b: color[2],
alpha: 1.0,
}
}
}
impl From<Laba> for Xyza {
fn from(
Laba {
lightness,
a,
b,
alpha,
}: Laba,
) -> Self {
// Based on http://www.brucelindbloom.com/index.html?Eqn_Lab_to_XYZ.html
let l = 100. * lightness;
let a = 100. * a;
let b = 100. * b;
let fy = (l + 16.0) / 116.0;
let fx = a / 500.0 + fy;
let fz = fy - b / 200.0;
let xr = {
let fx3 = ops::powf(fx, 3.0);
if fx3 > Laba::CIE_EPSILON {
fx3
} else {
(116.0 * fx - 16.0) / Laba::CIE_KAPPA
}
};
let yr = if l > Laba::CIE_EPSILON * Laba::CIE_KAPPA {
ops::powf((l + 16.0) / 116.0, 3.0)
} else {
l / Laba::CIE_KAPPA
};
let zr = {
let fz3 = ops::powf(fz, 3.0);
if fz3 > Laba::CIE_EPSILON {
fz3
} else {
(116.0 * fz - 16.0) / Laba::CIE_KAPPA
}
};
let x = xr * Xyza::D65_WHITE.x;
let y = yr * Xyza::D65_WHITE.y;
let z = zr * Xyza::D65_WHITE.z;
Xyza::new(x, y, z, alpha)
}
}
impl From<Xyza> for Laba {
fn from(Xyza { x, y, z, alpha }: Xyza) -> Self {
// Based on http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_Lab.html
let xr = x / Xyza::D65_WHITE.x;
let yr = y / Xyza::D65_WHITE.y;
let zr = z / Xyza::D65_WHITE.z;
let fx = if xr > Laba::CIE_EPSILON {
ops::cbrt(xr)
} else {
(Laba::CIE_KAPPA * xr + 16.0) / 116.0
};
let fy = if yr > Laba::CIE_EPSILON {
ops::cbrt(yr)
} else {
(Laba::CIE_KAPPA * yr + 16.0) / 116.0
};
let fz = if yr > Laba::CIE_EPSILON {
ops::cbrt(zr)
} else {
(Laba::CIE_KAPPA * zr + 16.0) / 116.0
};
let l = 1.16 * fy - 0.16;
let a = 5.00 * (fx - fy);
let b = 2.00 * (fy - fz);
Laba::new(l, a, b, alpha)
}
}
// Derived Conversions
impl From<Srgba> for Laba {
fn from(value: Srgba) -> Self {
Xyza::from(value).into()
}
}
impl From<Laba> for Srgba {
fn from(value: Laba) -> Self {
Xyza::from(value).into()
}
}
impl From<LinearRgba> for Laba {
fn from(value: LinearRgba) -> Self {
Xyza::from(value).into()
}
}
impl From<Laba> for LinearRgba {
fn from(value: Laba) -> Self {
Xyza::from(value).into()
}
}
impl From<Hsla> for Laba {
fn from(value: Hsla) -> Self {
Xyza::from(value).into()
}
}
impl From<Laba> for Hsla {
fn from(value: Laba) -> Self {
Xyza::from(value).into()
}
}
impl From<Hsva> for Laba {
fn from(value: Hsva) -> Self {
Xyza::from(value).into()
}
}
impl From<Laba> for Hsva {
fn from(value: Laba) -> Self {
Xyza::from(value).into()
}
}
impl From<Hwba> for Laba {
fn from(value: Hwba) -> Self {
Xyza::from(value).into()
}
}
impl From<Laba> for Hwba {
fn from(value: Laba) -> Self {
Xyza::from(value).into()
}
}
impl From<Oklaba> for Laba {
fn from(value: Oklaba) -> Self {
Xyza::from(value).into()
}
}
impl From<Laba> for Oklaba {
fn from(value: Laba) -> Self {
Xyza::from(value).into()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
color_difference::EuclideanDistance, test_colors::TEST_COLORS, testing::assert_approx_eq,
};
#[test]
fn test_to_from_srgba() {
for color in TEST_COLORS.iter() {
let rgb2: Srgba = (color.lab).into();
let laba: Laba = (color.rgb).into();
assert!(
color.rgb.distance(&rgb2) < 0.0001,
"{}: {:?} != {:?}",
color.name,
color.rgb,
rgb2
);
assert_approx_eq!(color.lab.lightness, laba.lightness, 0.001);
if laba.lightness > 0.01 {
assert_approx_eq!(color.lab.a, laba.a, 0.1);
}
if laba.lightness > 0.01 && laba.a > 0.01 {
assert!(
(color.lab.b - laba.b).abs() < 1.7,
"{:?} != {:?}",
color.lab,
laba
);
}
assert_approx_eq!(color.lab.alpha, laba.alpha, 0.001);
}
}
#[test]
fn test_to_from_linear() {
for color in TEST_COLORS.iter() {
let rgb2: LinearRgba = (color.lab).into();
let laba: Laba = (color.linear_rgb).into();
assert!(
color.linear_rgb.distance(&rgb2) < 0.0001,
"{}: {:?} != {:?}",
color.name,
color.linear_rgb,
rgb2
);
assert_approx_eq!(color.lab.lightness, laba.lightness, 0.001);
if laba.lightness > 0.01 {
assert_approx_eq!(color.lab.a, laba.a, 0.1);
}
if laba.lightness > 0.01 && laba.a > 0.01 {
assert!(
(color.lab.b - laba.b).abs() < 1.7,
"{:?} != {:?}",
color.lab,
laba
);
}
assert_approx_eq!(color.lab.alpha, laba.alpha, 0.001);
}
}
}

400
vendor/bevy_color/src/lcha.rs vendored Normal file
View File

@@ -0,0 +1,400 @@
use crate::{
Alpha, ColorToComponents, Gray, Hue, Laba, LinearRgba, Luminance, Mix, Srgba, StandardColor,
Xyza,
};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
/// Color in LCH color space, with alpha
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct Lcha {
/// The lightness channel. [0.0, 1.5]
pub lightness: f32,
/// The chroma channel. [0.0, 1.5]
pub chroma: f32,
/// The hue channel. [0.0, 360.0]
pub hue: f32,
/// The alpha channel. [0.0, 1.0]
pub alpha: f32,
}
impl StandardColor for Lcha {}
impl Lcha {
/// Construct a new [`Lcha`] color from components.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.5]
/// * `chroma` - Chroma channel. [0.0, 1.5]
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn new(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> Self {
Self {
lightness,
chroma,
hue,
alpha,
}
}
/// Construct a new [`Lcha`] color from (h, s, l) components, with the default alpha (1.0).
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.5]
/// * `chroma` - Chroma channel. [0.0, 1.5]
/// * `hue` - Hue channel. [0.0, 360.0]
pub const fn lch(lightness: f32, chroma: f32, hue: f32) -> Self {
Self {
lightness,
chroma,
hue,
alpha: 1.0,
}
}
/// Return a copy of this color with the chroma channel set to the given value.
pub const fn with_chroma(self, chroma: f32) -> Self {
Self { chroma, ..self }
}
/// Return a copy of this color with the lightness channel set to the given value.
pub const fn with_lightness(self, lightness: f32) -> Self {
Self { lightness, ..self }
}
/// Generate a deterministic but [quasi-randomly distributed](https://en.wikipedia.org/wiki/Low-discrepancy_sequence)
/// color from a provided `index`.
///
/// This can be helpful for generating debug colors.
///
/// # Examples
///
/// ```rust
/// # use bevy_color::Lcha;
/// // Unique color for an entity
/// # let entity_index = 123;
/// // let entity_index = entity.index();
/// let color = Lcha::sequential_dispersed(entity_index);
///
/// // Palette with 5 distinct hues
/// let palette = (0..5).map(Lcha::sequential_dispersed).collect::<Vec<_>>();
/// ```
pub fn sequential_dispersed(index: u32) -> Self {
const FRAC_U32MAX_GOLDEN_RATIO: u32 = 2654435769; // (u32::MAX / Φ) rounded up
const RATIO_360: f32 = 360.0 / u32::MAX as f32;
// from https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/
//
// Map a sequence of integers (eg: 154, 155, 156, 157, 158) into the [0.0..1.0] range,
// so that the closer the numbers are, the larger the difference of their image.
let hue = index.wrapping_mul(FRAC_U32MAX_GOLDEN_RATIO) as f32 * RATIO_360;
Self::lch(0.75, 0.35, hue)
}
}
impl Default for Lcha {
fn default() -> Self {
Self::new(1., 0., 0., 1.)
}
}
impl Mix for Lcha {
#[inline]
fn mix(&self, other: &Self, factor: f32) -> Self {
let n_factor = 1.0 - factor;
Self {
lightness: self.lightness * n_factor + other.lightness * factor,
chroma: self.chroma * n_factor + other.chroma * factor,
hue: crate::color_ops::lerp_hue(self.hue, other.hue, factor),
alpha: self.alpha * n_factor + other.alpha * factor,
}
}
}
impl Gray for Lcha {
const BLACK: Self = Self::new(0.0, 0.0, 0.0000136603785, 1.0);
const WHITE: Self = Self::new(1.0, 0.0, 0.0000136603785, 1.0);
}
impl Alpha for Lcha {
#[inline]
fn with_alpha(&self, alpha: f32) -> Self {
Self { alpha, ..*self }
}
#[inline]
fn alpha(&self) -> f32 {
self.alpha
}
#[inline]
fn set_alpha(&mut self, alpha: f32) {
self.alpha = alpha;
}
}
impl Hue for Lcha {
#[inline]
fn with_hue(&self, hue: f32) -> Self {
Self { hue, ..*self }
}
#[inline]
fn hue(&self) -> f32 {
self.hue
}
#[inline]
fn set_hue(&mut self, hue: f32) {
self.hue = hue;
}
}
impl Luminance for Lcha {
#[inline]
fn with_luminance(&self, lightness: f32) -> Self {
Self { lightness, ..*self }
}
fn luminance(&self) -> f32 {
self.lightness
}
fn darker(&self, amount: f32) -> Self {
Self::new(
(self.lightness - amount).max(0.),
self.chroma,
self.hue,
self.alpha,
)
}
fn lighter(&self, amount: f32) -> Self {
Self::new(
(self.lightness + amount).min(1.),
self.chroma,
self.hue,
self.alpha,
)
}
}
impl ColorToComponents for Lcha {
fn to_f32_array(self) -> [f32; 4] {
[self.lightness, self.chroma, self.hue, self.alpha]
}
fn to_f32_array_no_alpha(self) -> [f32; 3] {
[self.lightness, self.chroma, self.hue]
}
fn to_vec4(self) -> Vec4 {
Vec4::new(self.lightness, self.chroma, self.hue, self.alpha)
}
fn to_vec3(self) -> Vec3 {
Vec3::new(self.lightness, self.chroma, self.hue)
}
fn from_f32_array(color: [f32; 4]) -> Self {
Self {
lightness: color[0],
chroma: color[1],
hue: color[2],
alpha: color[3],
}
}
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self {
Self {
lightness: color[0],
chroma: color[1],
hue: color[2],
alpha: 1.0,
}
}
fn from_vec4(color: Vec4) -> Self {
Self {
lightness: color[0],
chroma: color[1],
hue: color[2],
alpha: color[3],
}
}
fn from_vec3(color: Vec3) -> Self {
Self {
lightness: color[0],
chroma: color[1],
hue: color[2],
alpha: 1.0,
}
}
}
impl From<Lcha> for Laba {
fn from(
Lcha {
lightness,
chroma,
hue,
alpha,
}: Lcha,
) -> Self {
// Based on http://www.brucelindbloom.com/index.html?Eqn_LCH_to_Lab.html
let l = lightness;
let (sin, cos) = ops::sin_cos(hue.to_radians());
let a = chroma * cos;
let b = chroma * sin;
Laba::new(l, a, b, alpha)
}
}
impl From<Laba> for Lcha {
fn from(
Laba {
lightness,
a,
b,
alpha,
}: Laba,
) -> Self {
// Based on http://www.brucelindbloom.com/index.html?Eqn_Lab_to_LCH.html
let c = ops::hypot(a, b);
let h = {
let h = ops::atan2(b.to_radians(), a.to_radians()).to_degrees();
if h < 0.0 {
h + 360.0
} else {
h
}
};
let chroma = c.clamp(0.0, 1.5);
let hue = h;
Lcha::new(lightness, chroma, hue, alpha)
}
}
// Derived Conversions
impl From<Srgba> for Lcha {
fn from(value: Srgba) -> Self {
Laba::from(value).into()
}
}
impl From<Lcha> for Srgba {
fn from(value: Lcha) -> Self {
Laba::from(value).into()
}
}
impl From<LinearRgba> for Lcha {
fn from(value: LinearRgba) -> Self {
Laba::from(value).into()
}
}
impl From<Lcha> for LinearRgba {
fn from(value: Lcha) -> Self {
Laba::from(value).into()
}
}
impl From<Xyza> for Lcha {
fn from(value: Xyza) -> Self {
Laba::from(value).into()
}
}
impl From<Lcha> for Xyza {
fn from(value: Lcha) -> Self {
Laba::from(value).into()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
color_difference::EuclideanDistance, test_colors::TEST_COLORS, testing::assert_approx_eq,
};
#[test]
fn test_to_from_srgba() {
for color in TEST_COLORS.iter() {
let rgb2: Srgba = (color.lch).into();
let lcha: Lcha = (color.rgb).into();
assert!(
color.rgb.distance(&rgb2) < 0.0001,
"{}: {:?} != {:?}",
color.name,
color.rgb,
rgb2
);
assert_approx_eq!(color.lch.lightness, lcha.lightness, 0.001);
if lcha.lightness > 0.01 {
assert_approx_eq!(color.lch.chroma, lcha.chroma, 0.1);
}
if lcha.lightness > 0.01 && lcha.chroma > 0.01 {
assert!(
(color.lch.hue - lcha.hue).abs() < 1.7,
"{:?} != {:?}",
color.lch,
lcha
);
}
assert_approx_eq!(color.lch.alpha, lcha.alpha, 0.001);
}
}
#[test]
fn test_to_from_linear() {
for color in TEST_COLORS.iter() {
let rgb2: LinearRgba = (color.lch).into();
let lcha: Lcha = (color.linear_rgb).into();
assert!(
color.linear_rgb.distance(&rgb2) < 0.0001,
"{}: {:?} != {:?}",
color.name,
color.linear_rgb,
rgb2
);
assert_approx_eq!(color.lch.lightness, lcha.lightness, 0.001);
if lcha.lightness > 0.01 {
assert_approx_eq!(color.lch.chroma, lcha.chroma, 0.1);
}
if lcha.lightness > 0.01 && lcha.chroma > 0.01 {
assert!(
(color.lch.hue - lcha.hue).abs() < 1.7,
"{:?} != {:?}",
color.lch,
lcha
);
}
assert_approx_eq!(color.lch.alpha, lcha.alpha, 0.001);
}
}
}

271
vendor/bevy_color/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,271 @@
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![forbid(unsafe_code)]
#![doc(
html_logo_url = "https://bevyengine.org/assets/icon.png",
html_favicon_url = "https://bevyengine.org/assets/icon.png"
)]
#![no_std]
//! Representations of colors in various color spaces.
//!
//! This crate provides a number of color representations, including:
//!
//! - [`Srgba`] (standard RGBA, with gamma correction)
//! - [`LinearRgba`] (linear RGBA, without gamma correction)
//! - [`Hsla`] (hue, saturation, lightness, alpha)
//! - [`Hsva`] (hue, saturation, value, alpha)
//! - [`Hwba`] (hue, whiteness, blackness, alpha)
//! - [`Laba`] (lightness, a-axis, b-axis, alpha)
//! - [`Lcha`] (lightness, chroma, hue, alpha)
//! - [`Oklaba`] (lightness, a-axis, b-axis, alpha)
//! - [`Oklcha`] (lightness, chroma, hue, alpha)
//! - [`Xyza`] (x-axis, y-axis, z-axis, alpha)
//!
//! Each of these color spaces is represented as a distinct Rust type.
//!
//! # Color Space Usage
//!
//! Rendering engines typically use linear RGBA colors, which allow for physically accurate
//! lighting calculations. However, linear RGBA colors are not perceptually uniform, because
//! both human eyes and computer monitors have non-linear responses to light. "Standard" RGBA
//! represents an industry-wide compromise designed to encode colors in a way that looks good to
//! humans in as few bits as possible, but it is not suitable for lighting calculations.
//!
//! Most image file formats and scene graph formats use standard RGBA, because graphic design
//! tools are intended to be used by humans. However, 3D lighting calculations operate in linear
//! RGBA, so it is important to convert standard colors to linear before sending them to the GPU.
//! Most Bevy APIs will handle this conversion automatically, but if you are writing a custom
//! shader, you will need to do this conversion yourself.
//!
//! HSL and LCH are "cylindrical" color spaces, which means they represent colors as a combination
//! of hue, saturation, and lightness (or chroma). These color spaces are useful for working
//! with colors in an artistic way - for example, when creating gradients or color palettes.
//! A gradient in HSL space from red to violet will produce a rainbow. The LCH color space is
//! more perceptually accurate than HSL, but is less intuitive to work with.
//!
//! HSV and HWB are very closely related to HSL in their derivation, having identical definitions for
//! hue. Where HSL uses saturation and lightness, HSV uses a slightly modified definition of saturation,
//! and an analog of lightness in the form of value. In contrast, HWB instead uses whiteness and blackness
//! parameters, which can be used to lighten and darken a particular hue respectively.
//!
//! Oklab and Oklch are perceptually uniform color spaces that are designed to be used for tasks such
//! as image processing. They are not as widely used as the other color spaces, but are useful
//! for tasks such as color correction and image analysis, where it is important to be able
//! to do things like change color saturation without causing hue shifts.
//!
//! XYZ is a foundational space commonly used in the definition of other more modern color
//! spaces. The space is more formally known as CIE 1931, where the `x` and `z` axes represent
//! a form of chromaticity, while `y` defines an illuminance level.
//!
//! See also the [Wikipedia article on color spaces](https://en.wikipedia.org/wiki/Color_space).
#![doc = include_str!("../docs/conversion.md")]
//! <div>
#![doc = include_str!("../docs/diagrams/model_graph.svg")]
//! </div>
//!
//! # Other Utilities
//!
//! The crate also provides a number of color operations, such as blending, color difference,
//! and color range operations.
//!
//! In addition, there is a [`Color`] enum that can represent any of the color
//! types in this crate. This is useful when you need to store a color in a data structure
//! that can't be generic over the color type.
//!
//! Color types that are either physically or perceptually linear also implement `Add<Self>`, `Sub<Self>`, `Mul<f32>` and `Div<f32>`
//! allowing you to use them with splines.
//!
//! Please note that most often adding or subtracting colors is not what you may want.
//! Please have a look at other operations like blending, lightening or mixing colors using e.g. [`Mix`] or [`Luminance`] instead.
//!
//! # Example
//!
//! ```
//! use bevy_color::{Srgba, Hsla};
//!
//! let srgba = Srgba::new(0.5, 0.2, 0.8, 1.0);
//! let hsla: Hsla = srgba.into();
//!
//! println!("Srgba: {:?}", srgba);
//! println!("Hsla: {:?}", hsla);
//! ```
#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "alloc")]
extern crate alloc;
mod color;
pub mod color_difference;
#[cfg(feature = "alloc")]
mod color_gradient;
mod color_ops;
mod color_range;
mod hsla;
mod hsva;
mod hwba;
mod laba;
mod lcha;
mod linear_rgba;
mod oklaba;
mod oklcha;
pub mod palettes;
mod srgba;
#[cfg(test)]
mod test_colors;
#[cfg(test)]
mod testing;
mod xyza;
/// The color prelude.
///
/// This includes the most common types in this crate, re-exported for your convenience.
pub mod prelude {
pub use crate::{
color::*, color_ops::*, hsla::*, hsva::*, hwba::*, laba::*, lcha::*, linear_rgba::*,
oklaba::*, oklcha::*, srgba::*, xyza::*,
};
}
pub use color::*;
#[cfg(feature = "alloc")]
pub use color_gradient::*;
pub use color_ops::*;
pub use color_range::*;
pub use hsla::*;
pub use hsva::*;
pub use hwba::*;
pub use laba::*;
pub use lcha::*;
pub use linear_rgba::*;
pub use oklaba::*;
pub use oklcha::*;
pub use srgba::*;
pub use xyza::*;
/// Describes the traits that a color should implement for consistency.
#[expect(
clippy::allow_attributes,
reason = "If the below attribute on `dead_code` is removed, then rustc complains that `StandardColor` is dead code. However, if we `expect` the `dead_code` lint, then rustc complains of an unfulfilled expectation."
)]
#[allow(
dead_code,
reason = "This is an internal marker trait used to ensure that our color types impl the required traits"
)]
pub(crate) trait StandardColor
where
Self: core::fmt::Debug,
Self: Clone + Copy,
Self: PartialEq,
Self: Default,
Self: From<Color> + Into<Color>,
Self: From<Srgba> + Into<Srgba>,
Self: From<LinearRgba> + Into<LinearRgba>,
Self: From<Hsla> + Into<Hsla>,
Self: From<Hsva> + Into<Hsva>,
Self: From<Hwba> + Into<Hwba>,
Self: From<Laba> + Into<Laba>,
Self: From<Lcha> + Into<Lcha>,
Self: From<Oklaba> + Into<Oklaba>,
Self: From<Oklcha> + Into<Oklcha>,
Self: From<Xyza> + Into<Xyza>,
Self: Alpha,
{
}
macro_rules! impl_componentwise_vector_space {
($ty: ident, [$($element: ident),+]) => {
impl core::ops::Add<Self> for $ty {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self::Output {
$($element: self.$element + rhs.$element,)+
}
}
}
impl core::ops::AddAssign<Self> for $ty {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs;
}
}
impl core::ops::Neg for $ty {
type Output = Self;
fn neg(self) -> Self::Output {
Self::Output {
$($element: -self.$element,)+
}
}
}
impl core::ops::Sub<Self> for $ty {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
Self::Output {
$($element: self.$element - rhs.$element,)+
}
}
}
impl core::ops::SubAssign<Self> for $ty {
fn sub_assign(&mut self, rhs: Self) {
*self = *self - rhs;
}
}
impl core::ops::Mul<f32> for $ty {
type Output = Self;
fn mul(self, rhs: f32) -> Self::Output {
Self::Output {
$($element: self.$element * rhs,)+
}
}
}
impl core::ops::Mul<$ty> for f32 {
type Output = $ty;
fn mul(self, rhs: $ty) -> Self::Output {
Self::Output {
$($element: self * rhs.$element,)+
}
}
}
impl core::ops::MulAssign<f32> for $ty {
fn mul_assign(&mut self, rhs: f32) {
*self = *self * rhs;
}
}
impl core::ops::Div<f32> for $ty {
type Output = Self;
fn div(self, rhs: f32) -> Self::Output {
Self::Output {
$($element: self.$element / rhs,)+
}
}
}
impl core::ops::DivAssign<f32> for $ty {
fn div_assign(&mut self, rhs: f32) {
*self = *self / rhs;
}
}
impl bevy_math::VectorSpace for $ty {
const ZERO: Self = Self {
$($element: 0.0,)+
};
}
};
}
pub(crate) use impl_componentwise_vector_space;

478
vendor/bevy_color/src/linear_rgba.rs vendored Normal file
View File

@@ -0,0 +1,478 @@
use crate::{
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
ColorToPacked, Gray, Luminance, Mix, StandardColor,
};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
use bytemuck::{Pod, Zeroable};
/// Linear RGB color with alpha.
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq, Pod, Zeroable)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
#[repr(C)]
pub struct LinearRgba {
/// The red channel. [0.0, 1.0]
pub red: f32,
/// The green channel. [0.0, 1.0]
pub green: f32,
/// The blue channel. [0.0, 1.0]
pub blue: f32,
/// The alpha channel. [0.0, 1.0]
pub alpha: f32,
}
impl StandardColor for LinearRgba {}
impl_componentwise_vector_space!(LinearRgba, [red, green, blue, alpha]);
impl LinearRgba {
/// A fully black color with full alpha.
pub const BLACK: Self = Self {
red: 0.0,
green: 0.0,
blue: 0.0,
alpha: 1.0,
};
/// A fully white color with full alpha.
pub const WHITE: Self = Self {
red: 1.0,
green: 1.0,
blue: 1.0,
alpha: 1.0,
};
/// A fully transparent color.
pub const NONE: Self = Self {
red: 0.0,
green: 0.0,
blue: 0.0,
alpha: 0.0,
};
/// A fully red color with full alpha.
pub const RED: Self = Self {
red: 1.0,
green: 0.0,
blue: 0.0,
alpha: 1.0,
};
/// A fully green color with full alpha.
pub const GREEN: Self = Self {
red: 0.0,
green: 1.0,
blue: 0.0,
alpha: 1.0,
};
/// A fully blue color with full alpha.
pub const BLUE: Self = Self {
red: 0.0,
green: 0.0,
blue: 1.0,
alpha: 1.0,
};
/// An invalid color.
///
/// This type can be used to represent an invalid color value;
/// in some rendering applications the color will be ignored,
/// enabling performant hacks like hiding lines by setting their color to `INVALID`.
pub const NAN: Self = Self {
red: f32::NAN,
green: f32::NAN,
blue: f32::NAN,
alpha: f32::NAN,
};
/// Construct a new [`LinearRgba`] color from components.
pub const fn new(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
Self {
red,
green,
blue,
alpha,
}
}
/// Construct a new [`LinearRgba`] color from (r, g, b) components, with the default alpha (1.0).
///
/// # Arguments
///
/// * `red` - Red channel. [0.0, 1.0]
/// * `green` - Green channel. [0.0, 1.0]
/// * `blue` - Blue channel. [0.0, 1.0]
pub const fn rgb(red: f32, green: f32, blue: f32) -> Self {
Self {
red,
green,
blue,
alpha: 1.0,
}
}
/// Return a copy of this color with the red channel set to the given value.
pub const fn with_red(self, red: f32) -> Self {
Self { red, ..self }
}
/// Return a copy of this color with the green channel set to the given value.
pub const fn with_green(self, green: f32) -> Self {
Self { green, ..self }
}
/// Return a copy of this color with the blue channel set to the given value.
pub const fn with_blue(self, blue: f32) -> Self {
Self { blue, ..self }
}
/// Make the color lighter or darker by some amount
fn adjust_lightness(&mut self, amount: f32) {
let luminance = self.luminance();
let target_luminance = (luminance + amount).clamp(0.0, 1.0);
if target_luminance < luminance {
let adjustment = (luminance - target_luminance) / luminance;
self.mix_assign(Self::new(0.0, 0.0, 0.0, self.alpha), adjustment);
} else if target_luminance > luminance {
let adjustment = (target_luminance - luminance) / (1. - luminance);
self.mix_assign(Self::new(1.0, 1.0, 1.0, self.alpha), adjustment);
}
}
/// Converts this color to a u32.
///
/// Maps the RGBA channels in RGBA order to a little-endian byte array (GPUs are little-endian).
/// `A` will be the most significant byte and `R` the least significant.
pub fn as_u32(&self) -> u32 {
u32::from_le_bytes(self.to_u8_array())
}
}
impl Default for LinearRgba {
/// Construct a new [`LinearRgba`] color with the default values (white with full alpha).
fn default() -> Self {
Self::WHITE
}
}
impl Luminance for LinearRgba {
/// Luminance calculated using the [CIE XYZ formula](https://en.wikipedia.org/wiki/Relative_luminance).
#[inline]
fn luminance(&self) -> f32 {
self.red * 0.2126 + self.green * 0.7152 + self.blue * 0.0722
}
#[inline]
fn with_luminance(&self, luminance: f32) -> Self {
let current_luminance = self.luminance();
let adjustment = luminance / current_luminance;
Self {
red: (self.red * adjustment).clamp(0., 1.),
green: (self.green * adjustment).clamp(0., 1.),
blue: (self.blue * adjustment).clamp(0., 1.),
alpha: self.alpha,
}
}
#[inline]
fn darker(&self, amount: f32) -> Self {
let mut result = *self;
result.adjust_lightness(-amount);
result
}
#[inline]
fn lighter(&self, amount: f32) -> Self {
let mut result = *self;
result.adjust_lightness(amount);
result
}
}
impl Mix for LinearRgba {
#[inline]
fn mix(&self, other: &Self, factor: f32) -> Self {
let n_factor = 1.0 - factor;
Self {
red: self.red * n_factor + other.red * factor,
green: self.green * n_factor + other.green * factor,
blue: self.blue * n_factor + other.blue * factor,
alpha: self.alpha * n_factor + other.alpha * factor,
}
}
}
impl Gray for LinearRgba {
const BLACK: Self = Self::BLACK;
const WHITE: Self = Self::WHITE;
}
impl Alpha for LinearRgba {
#[inline]
fn with_alpha(&self, alpha: f32) -> Self {
Self { alpha, ..*self }
}
#[inline]
fn alpha(&self) -> f32 {
self.alpha
}
#[inline]
fn set_alpha(&mut self, alpha: f32) {
self.alpha = alpha;
}
}
impl EuclideanDistance for LinearRgba {
#[inline]
fn distance_squared(&self, other: &Self) -> f32 {
let dr = self.red - other.red;
let dg = self.green - other.green;
let db = self.blue - other.blue;
dr * dr + dg * dg + db * db
}
}
impl ColorToComponents for LinearRgba {
fn to_f32_array(self) -> [f32; 4] {
[self.red, self.green, self.blue, self.alpha]
}
fn to_f32_array_no_alpha(self) -> [f32; 3] {
[self.red, self.green, self.blue]
}
fn to_vec4(self) -> Vec4 {
Vec4::new(self.red, self.green, self.blue, self.alpha)
}
fn to_vec3(self) -> Vec3 {
Vec3::new(self.red, self.green, self.blue)
}
fn from_f32_array(color: [f32; 4]) -> Self {
Self {
red: color[0],
green: color[1],
blue: color[2],
alpha: color[3],
}
}
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self {
Self {
red: color[0],
green: color[1],
blue: color[2],
alpha: 1.0,
}
}
fn from_vec4(color: Vec4) -> Self {
Self {
red: color[0],
green: color[1],
blue: color[2],
alpha: color[3],
}
}
fn from_vec3(color: Vec3) -> Self {
Self {
red: color[0],
green: color[1],
blue: color[2],
alpha: 1.0,
}
}
}
impl ColorToPacked for LinearRgba {
fn to_u8_array(self) -> [u8; 4] {
[self.red, self.green, self.blue, self.alpha]
.map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
}
fn to_u8_array_no_alpha(self) -> [u8; 3] {
[self.red, self.green, self.blue].map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
}
fn from_u8_array(color: [u8; 4]) -> Self {
Self::from_f32_array(color.map(|u| u as f32 / 255.0))
}
fn from_u8_array_no_alpha(color: [u8; 3]) -> Self {
Self::from_f32_array_no_alpha(color.map(|u| u as f32 / 255.0))
}
}
#[cfg(feature = "wgpu-types")]
impl From<LinearRgba> for wgpu_types::Color {
fn from(color: LinearRgba) -> Self {
wgpu_types::Color {
r: color.red as f64,
g: color.green as f64,
b: color.blue as f64,
a: color.alpha as f64,
}
}
}
// [`LinearRgba`] is intended to be used with shaders
// So it's the only color type that implements [`ShaderType`] to make it easier to use inside shaders
#[cfg(feature = "encase")]
impl encase::ShaderType for LinearRgba {
type ExtraMetadata = ();
const METADATA: encase::private::Metadata<Self::ExtraMetadata> = {
let size =
encase::private::SizeValue::from(<f32 as encase::private::ShaderSize>::SHADER_SIZE)
.mul(4);
let alignment = encase::private::AlignmentValue::from_next_power_of_two_size(size);
encase::private::Metadata {
alignment,
has_uniform_min_alignment: false,
is_pod: true,
min_size: size,
extra: (),
}
};
const UNIFORM_COMPAT_ASSERT: fn() = || {};
}
#[cfg(feature = "encase")]
impl encase::private::WriteInto for LinearRgba {
fn write_into<B: encase::private::BufferMut>(&self, writer: &mut encase::private::Writer<B>) {
for el in &[self.red, self.green, self.blue, self.alpha] {
encase::private::WriteInto::write_into(el, writer);
}
}
}
#[cfg(feature = "encase")]
impl encase::private::ReadFrom for LinearRgba {
fn read_from<B: encase::private::BufferRef>(
&mut self,
reader: &mut encase::private::Reader<B>,
) {
let mut buffer = [0.0f32; 4];
for el in &mut buffer {
encase::private::ReadFrom::read_from(el, reader);
}
*self = LinearRgba {
red: buffer[0],
green: buffer[1],
blue: buffer[2],
alpha: buffer[3],
}
}
}
#[cfg(feature = "encase")]
impl encase::private::CreateFrom for LinearRgba {
fn create_from<B>(reader: &mut encase::private::Reader<B>) -> Self
where
B: encase::private::BufferRef,
{
// These are intentionally not inlined in the constructor to make this
// resilient to internal Color refactors / implicit type changes.
let red: f32 = encase::private::CreateFrom::create_from(reader);
let green: f32 = encase::private::CreateFrom::create_from(reader);
let blue: f32 = encase::private::CreateFrom::create_from(reader);
let alpha: f32 = encase::private::CreateFrom::create_from(reader);
LinearRgba {
red,
green,
blue,
alpha,
}
}
}
#[cfg(feature = "encase")]
impl encase::ShaderSize for LinearRgba {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn euclidean_distance() {
// White to black
let a = LinearRgba::new(0.0, 0.0, 0.0, 1.0);
let b = LinearRgba::new(1.0, 1.0, 1.0, 1.0);
assert_eq!(a.distance_squared(&b), 3.0);
// Alpha shouldn't matter
let a = LinearRgba::new(0.0, 0.0, 0.0, 1.0);
let b = LinearRgba::new(1.0, 1.0, 1.0, 0.0);
assert_eq!(a.distance_squared(&b), 3.0);
// Red to green
let a = LinearRgba::new(0.0, 0.0, 0.0, 1.0);
let b = LinearRgba::new(1.0, 0.0, 0.0, 1.0);
assert_eq!(a.distance_squared(&b), 1.0);
}
#[test]
fn to_and_from_u8() {
// from_u8_array
let a = LinearRgba::from_u8_array([255, 0, 0, 255]);
let b = LinearRgba::new(1.0, 0.0, 0.0, 1.0);
assert_eq!(a, b);
// from_u8_array_no_alpha
let a = LinearRgba::from_u8_array_no_alpha([255, 255, 0]);
let b = LinearRgba::rgb(1.0, 1.0, 0.0);
assert_eq!(a, b);
// to_u8_array
let a = LinearRgba::new(0.0, 0.0, 1.0, 1.0).to_u8_array();
let b = [0, 0, 255, 255];
assert_eq!(a, b);
// to_u8_array_no_alpha
let a = LinearRgba::rgb(0.0, 1.0, 1.0).to_u8_array_no_alpha();
let b = [0, 255, 255];
assert_eq!(a, b);
// clamping
let a = LinearRgba::rgb(0.0, 100.0, -100.0).to_u8_array_no_alpha();
let b = [0, 255, 0];
assert_eq!(a, b);
}
#[test]
fn darker_lighter() {
// Darker and lighter should be commutative.
let color = LinearRgba::new(0.4, 0.5, 0.6, 1.0);
let darker1 = color.darker(0.1);
let darker2 = darker1.darker(0.1);
let twice_as_dark = color.darker(0.2);
assert!(darker2.distance_squared(&twice_as_dark) < 0.0001);
let lighter1 = color.lighter(0.1);
let lighter2 = lighter1.lighter(0.1);
let twice_as_light = color.lighter(0.2);
assert!(lighter2.distance_squared(&twice_as_light) < 0.0001);
}
}

400
vendor/bevy_color/src/oklaba.rs vendored Normal file
View File

@@ -0,0 +1,400 @@
use crate::{
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
Gray, Hsla, Hsva, Hwba, Lcha, LinearRgba, Luminance, Mix, Srgba, StandardColor, Xyza,
};
use bevy_math::{ops, FloatPow, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
/// Color in Oklab color space, with alpha
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct Oklaba {
/// The 'lightness' channel. [0.0, 1.0]
pub lightness: f32,
/// The 'a' channel. [-1.0, 1.0]
pub a: f32,
/// The 'b' channel. [-1.0, 1.0]
pub b: f32,
/// The alpha channel. [0.0, 1.0]
pub alpha: f32,
}
impl StandardColor for Oklaba {}
impl_componentwise_vector_space!(Oklaba, [lightness, a, b, alpha]);
impl Oklaba {
/// Construct a new [`Oklaba`] color from components.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.0]
/// * `a` - Green-red channel. [-1.0, 1.0]
/// * `b` - Blue-yellow channel. [-1.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn new(lightness: f32, a: f32, b: f32, alpha: f32) -> Self {
Self {
lightness,
a,
b,
alpha,
}
}
/// Construct a new [`Oklaba`] color from (l, a, b) components, with the default alpha (1.0).
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.0]
/// * `a` - Green-red channel. [-1.0, 1.0]
/// * `b` - Blue-yellow channel. [-1.0, 1.0]
pub const fn lab(lightness: f32, a: f32, b: f32) -> Self {
Self {
lightness,
a,
b,
alpha: 1.0,
}
}
/// Return a copy of this color with the 'lightness' channel set to the given value.
pub const fn with_lightness(self, lightness: f32) -> Self {
Self { lightness, ..self }
}
/// Return a copy of this color with the 'a' channel set to the given value.
pub const fn with_a(self, a: f32) -> Self {
Self { a, ..self }
}
/// Return a copy of this color with the 'b' channel set to the given value.
pub const fn with_b(self, b: f32) -> Self {
Self { b, ..self }
}
}
impl Default for Oklaba {
fn default() -> Self {
Self::new(1., 0., 0., 1.)
}
}
impl Mix for Oklaba {
#[inline]
fn mix(&self, other: &Self, factor: f32) -> Self {
let n_factor = 1.0 - factor;
Self {
lightness: self.lightness * n_factor + other.lightness * factor,
a: self.a * n_factor + other.a * factor,
b: self.b * n_factor + other.b * factor,
alpha: self.alpha * n_factor + other.alpha * factor,
}
}
}
impl Gray for Oklaba {
const BLACK: Self = Self::new(0., 0., 0., 1.);
const WHITE: Self = Self::new(1.0, 0.0, 0.000000059604645, 1.0);
}
impl Alpha for Oklaba {
#[inline]
fn with_alpha(&self, alpha: f32) -> Self {
Self { alpha, ..*self }
}
#[inline]
fn alpha(&self) -> f32 {
self.alpha
}
#[inline]
fn set_alpha(&mut self, alpha: f32) {
self.alpha = alpha;
}
}
impl Luminance for Oklaba {
#[inline]
fn with_luminance(&self, lightness: f32) -> Self {
Self { lightness, ..*self }
}
fn luminance(&self) -> f32 {
self.lightness
}
fn darker(&self, amount: f32) -> Self {
Self::new(
(self.lightness - amount).max(0.),
self.a,
self.b,
self.alpha,
)
}
fn lighter(&self, amount: f32) -> Self {
Self::new(
(self.lightness + amount).min(1.),
self.a,
self.b,
self.alpha,
)
}
}
impl EuclideanDistance for Oklaba {
#[inline]
fn distance_squared(&self, other: &Self) -> f32 {
(self.lightness - other.lightness).squared()
+ (self.a - other.a).squared()
+ (self.b - other.b).squared()
}
}
impl ColorToComponents for Oklaba {
fn to_f32_array(self) -> [f32; 4] {
[self.lightness, self.a, self.b, self.alpha]
}
fn to_f32_array_no_alpha(self) -> [f32; 3] {
[self.lightness, self.a, self.b]
}
fn to_vec4(self) -> Vec4 {
Vec4::new(self.lightness, self.a, self.b, self.alpha)
}
fn to_vec3(self) -> Vec3 {
Vec3::new(self.lightness, self.a, self.b)
}
fn from_f32_array(color: [f32; 4]) -> Self {
Self {
lightness: color[0],
a: color[1],
b: color[2],
alpha: color[3],
}
}
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self {
Self {
lightness: color[0],
a: color[1],
b: color[2],
alpha: 1.0,
}
}
fn from_vec4(color: Vec4) -> Self {
Self {
lightness: color[0],
a: color[1],
b: color[2],
alpha: color[3],
}
}
fn from_vec3(color: Vec3) -> Self {
Self {
lightness: color[0],
a: color[1],
b: color[2],
alpha: 1.0,
}
}
}
impl From<LinearRgba> for Oklaba {
fn from(value: LinearRgba) -> Self {
let LinearRgba {
red,
green,
blue,
alpha,
} = value;
// From https://bottosson.github.io/posts/oklab/#converting-from-linear-srgb-to-oklab
// Float literals are truncated to avoid excessive precision.
let l = 0.41222146 * red + 0.53633255 * green + 0.051445995 * blue;
let m = 0.2119035 * red + 0.6806995 * green + 0.10739696 * blue;
let s = 0.08830246 * red + 0.28171885 * green + 0.6299787 * blue;
let l_ = ops::cbrt(l);
let m_ = ops::cbrt(m);
let s_ = ops::cbrt(s);
let l = 0.21045426 * l_ + 0.7936178 * m_ - 0.004072047 * s_;
let a = 1.9779985 * l_ - 2.4285922 * m_ + 0.4505937 * s_;
let b = 0.025904037 * l_ + 0.78277177 * m_ - 0.80867577 * s_;
Oklaba::new(l, a, b, alpha)
}
}
impl From<Oklaba> for LinearRgba {
fn from(value: Oklaba) -> Self {
let Oklaba {
lightness,
a,
b,
alpha,
} = value;
// From https://bottosson.github.io/posts/oklab/#converting-from-linear-srgb-to-oklab
// Float literals are truncated to avoid excessive precision.
let l_ = lightness + 0.39633778 * a + 0.21580376 * b;
let m_ = lightness - 0.105561346 * a - 0.06385417 * b;
let s_ = lightness - 0.08948418 * a - 1.2914855 * b;
let l = l_ * l_ * l_;
let m = m_ * m_ * m_;
let s = s_ * s_ * s_;
let red = 4.0767417 * l - 3.3077116 * m + 0.23096994 * s;
let green = -1.268438 * l + 2.6097574 * m - 0.34131938 * s;
let blue = -0.0041960863 * l - 0.7034186 * m + 1.7076147 * s;
Self {
red,
green,
blue,
alpha,
}
}
}
// Derived Conversions
impl From<Hsla> for Oklaba {
fn from(value: Hsla) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Oklaba> for Hsla {
fn from(value: Oklaba) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Hsva> for Oklaba {
fn from(value: Hsva) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Oklaba> for Hsva {
fn from(value: Oklaba) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Hwba> for Oklaba {
fn from(value: Hwba) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Oklaba> for Hwba {
fn from(value: Oklaba) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Lcha> for Oklaba {
fn from(value: Lcha) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Oklaba> for Lcha {
fn from(value: Oklaba) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Srgba> for Oklaba {
fn from(value: Srgba) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Oklaba> for Srgba {
fn from(value: Oklaba) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Xyza> for Oklaba {
fn from(value: Xyza) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Oklaba> for Xyza {
fn from(value: Oklaba) -> Self {
LinearRgba::from(value).into()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{test_colors::TEST_COLORS, testing::assert_approx_eq};
#[test]
fn test_to_from_srgba() {
let oklaba = Oklaba::new(0.5, 0.5, 0.5, 1.0);
let srgba: Srgba = oklaba.into();
let oklaba2: Oklaba = srgba.into();
assert_approx_eq!(oklaba.lightness, oklaba2.lightness, 0.001);
assert_approx_eq!(oklaba.a, oklaba2.a, 0.001);
assert_approx_eq!(oklaba.b, oklaba2.b, 0.001);
assert_approx_eq!(oklaba.alpha, oklaba2.alpha, 0.001);
}
#[test]
fn test_to_from_srgba_2() {
for color in TEST_COLORS.iter() {
let rgb2: Srgba = (color.oklab).into();
let oklab: Oklaba = (color.rgb).into();
assert!(
color.rgb.distance(&rgb2) < 0.0001,
"{}: {:?} != {:?}",
color.name,
color.rgb,
rgb2
);
assert!(
color.oklab.distance(&oklab) < 0.0001,
"{}: {:?} != {:?}",
color.name,
color.oklab,
oklab
);
}
}
#[test]
fn test_to_from_linear() {
let oklaba = Oklaba::new(0.5, 0.5, 0.5, 1.0);
let linear: LinearRgba = oklaba.into();
let oklaba2: Oklaba = linear.into();
assert_approx_eq!(oklaba.lightness, oklaba2.lightness, 0.001);
assert_approx_eq!(oklaba.a, oklaba2.a, 0.001);
assert_approx_eq!(oklaba.b, oklaba2.b, 0.001);
assert_approx_eq!(oklaba.alpha, oklaba2.alpha, 0.001);
}
}

440
vendor/bevy_color/src/oklcha.rs vendored Normal file
View File

@@ -0,0 +1,440 @@
use crate::{
color_difference::EuclideanDistance, Alpha, ColorToComponents, Gray, Hsla, Hsva, Hue, Hwba,
Laba, Lcha, LinearRgba, Luminance, Mix, Oklaba, Srgba, StandardColor, Xyza,
};
use bevy_math::{ops, FloatPow, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
/// Color in Oklch color space, with alpha
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct Oklcha {
/// The 'lightness' channel. [0.0, 1.0]
pub lightness: f32,
/// The 'chroma' channel. [0.0, 1.0]
pub chroma: f32,
/// The 'hue' channel. [0.0, 360.0]
pub hue: f32,
/// The alpha channel. [0.0, 1.0]
pub alpha: f32,
}
impl StandardColor for Oklcha {}
impl Oklcha {
/// Construct a new [`Oklcha`] color from components.
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.0]
/// * `chroma` - Chroma channel. [0.0, 1.0]
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn new(lightness: f32, chroma: f32, hue: f32, alpha: f32) -> Self {
Self {
lightness,
chroma,
hue,
alpha,
}
}
/// Construct a new [`Oklcha`] color from (l, c, h) components, with the default alpha (1.0).
///
/// # Arguments
///
/// * `lightness` - Lightness channel. [0.0, 1.0]
/// * `chroma` - Chroma channel. [0.0, 1.0]
/// * `hue` - Hue channel. [0.0, 360.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn lch(lightness: f32, chroma: f32, hue: f32) -> Self {
Self::new(lightness, chroma, hue, 1.0)
}
/// Return a copy of this color with the 'lightness' channel set to the given value.
pub const fn with_lightness(self, lightness: f32) -> Self {
Self { lightness, ..self }
}
/// Return a copy of this color with the 'chroma' channel set to the given value.
pub const fn with_chroma(self, chroma: f32) -> Self {
Self { chroma, ..self }
}
/// Generate a deterministic but [quasi-randomly distributed](https://en.wikipedia.org/wiki/Low-discrepancy_sequence)
/// color from a provided `index`.
///
/// This can be helpful for generating debug colors.
///
/// # Examples
///
/// ```rust
/// # use bevy_color::Oklcha;
/// // Unique color for an entity
/// # let entity_index = 123;
/// // let entity_index = entity.index();
/// let color = Oklcha::sequential_dispersed(entity_index);
///
/// // Palette with 5 distinct hues
/// let palette = (0..5).map(Oklcha::sequential_dispersed).collect::<Vec<_>>();
/// ```
pub fn sequential_dispersed(index: u32) -> Self {
const FRAC_U32MAX_GOLDEN_RATIO: u32 = 2654435769; // (u32::MAX / Φ) rounded up
const RATIO_360: f32 = 360.0 / u32::MAX as f32;
// from https://extremelearning.com.au/unreasonable-effectiveness-of-quasirandom-sequences/
//
// Map a sequence of integers (eg: 154, 155, 156, 157, 158) into the [0.0..1.0] range,
// so that the closer the numbers are, the larger the difference of their image.
let hue = index.wrapping_mul(FRAC_U32MAX_GOLDEN_RATIO) as f32 * RATIO_360;
Self::lch(0.75, 0.1, hue)
}
}
impl Default for Oklcha {
fn default() -> Self {
Self::new(1., 0., 0., 1.)
}
}
impl Mix for Oklcha {
#[inline]
fn mix(&self, other: &Self, factor: f32) -> Self {
let n_factor = 1.0 - factor;
Self {
lightness: self.lightness * n_factor + other.lightness * factor,
chroma: self.chroma * n_factor + other.chroma * factor,
hue: crate::color_ops::lerp_hue(self.hue, other.hue, factor),
alpha: self.alpha * n_factor + other.alpha * factor,
}
}
}
impl Gray for Oklcha {
const BLACK: Self = Self::new(0., 0., 0., 1.);
const WHITE: Self = Self::new(1.0, 0.000000059604645, 90.0, 1.0);
}
impl Alpha for Oklcha {
#[inline]
fn with_alpha(&self, alpha: f32) -> Self {
Self { alpha, ..*self }
}
#[inline]
fn alpha(&self) -> f32 {
self.alpha
}
#[inline]
fn set_alpha(&mut self, alpha: f32) {
self.alpha = alpha;
}
}
impl Hue for Oklcha {
#[inline]
fn with_hue(&self, hue: f32) -> Self {
Self { hue, ..*self }
}
#[inline]
fn hue(&self) -> f32 {
self.hue
}
#[inline]
fn set_hue(&mut self, hue: f32) {
self.hue = hue;
}
}
impl Luminance for Oklcha {
#[inline]
fn with_luminance(&self, lightness: f32) -> Self {
Self { lightness, ..*self }
}
fn luminance(&self) -> f32 {
self.lightness
}
fn darker(&self, amount: f32) -> Self {
Self::new(
(self.lightness - amount).max(0.),
self.chroma,
self.hue,
self.alpha,
)
}
fn lighter(&self, amount: f32) -> Self {
Self::new(
(self.lightness + amount).min(1.),
self.chroma,
self.hue,
self.alpha,
)
}
}
impl EuclideanDistance for Oklcha {
#[inline]
fn distance_squared(&self, other: &Self) -> f32 {
(self.lightness - other.lightness).squared()
+ (self.chroma - other.chroma).squared()
+ (self.hue - other.hue).squared()
}
}
impl ColorToComponents for Oklcha {
fn to_f32_array(self) -> [f32; 4] {
[self.lightness, self.chroma, self.hue, self.alpha]
}
fn to_f32_array_no_alpha(self) -> [f32; 3] {
[self.lightness, self.chroma, self.hue]
}
fn to_vec4(self) -> Vec4 {
Vec4::new(self.lightness, self.chroma, self.hue, self.alpha)
}
fn to_vec3(self) -> Vec3 {
Vec3::new(self.lightness, self.chroma, self.hue)
}
fn from_f32_array(color: [f32; 4]) -> Self {
Self {
lightness: color[0],
chroma: color[1],
hue: color[2],
alpha: color[3],
}
}
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self {
Self {
lightness: color[0],
chroma: color[1],
hue: color[2],
alpha: 1.0,
}
}
fn from_vec4(color: Vec4) -> Self {
Self {
lightness: color[0],
chroma: color[1],
hue: color[2],
alpha: color[3],
}
}
fn from_vec3(color: Vec3) -> Self {
Self {
lightness: color[0],
chroma: color[1],
hue: color[2],
alpha: 1.0,
}
}
}
impl From<Oklaba> for Oklcha {
fn from(
Oklaba {
lightness,
a,
b,
alpha,
}: Oklaba,
) -> Self {
let chroma = ops::hypot(a, b);
let hue = ops::atan2(b, a).to_degrees();
let hue = if hue < 0.0 { hue + 360.0 } else { hue };
Oklcha::new(lightness, chroma, hue, alpha)
}
}
impl From<Oklcha> for Oklaba {
fn from(
Oklcha {
lightness,
chroma,
hue,
alpha,
}: Oklcha,
) -> Self {
let l = lightness;
let (sin, cos) = ops::sin_cos(hue.to_radians());
let a = chroma * cos;
let b = chroma * sin;
Oklaba::new(l, a, b, alpha)
}
}
// Derived Conversions
impl From<Hsla> for Oklcha {
fn from(value: Hsla) -> Self {
Oklaba::from(value).into()
}
}
impl From<Oklcha> for Hsla {
fn from(value: Oklcha) -> Self {
Oklaba::from(value).into()
}
}
impl From<Hsva> for Oklcha {
fn from(value: Hsva) -> Self {
Oklaba::from(value).into()
}
}
impl From<Oklcha> for Hsva {
fn from(value: Oklcha) -> Self {
Oklaba::from(value).into()
}
}
impl From<Hwba> for Oklcha {
fn from(value: Hwba) -> Self {
Oklaba::from(value).into()
}
}
impl From<Oklcha> for Hwba {
fn from(value: Oklcha) -> Self {
Oklaba::from(value).into()
}
}
impl From<Laba> for Oklcha {
fn from(value: Laba) -> Self {
Oklaba::from(value).into()
}
}
impl From<Oklcha> for Laba {
fn from(value: Oklcha) -> Self {
Oklaba::from(value).into()
}
}
impl From<Lcha> for Oklcha {
fn from(value: Lcha) -> Self {
Oklaba::from(value).into()
}
}
impl From<Oklcha> for Lcha {
fn from(value: Oklcha) -> Self {
Oklaba::from(value).into()
}
}
impl From<LinearRgba> for Oklcha {
fn from(value: LinearRgba) -> Self {
Oklaba::from(value).into()
}
}
impl From<Oklcha> for LinearRgba {
fn from(value: Oklcha) -> Self {
Oklaba::from(value).into()
}
}
impl From<Srgba> for Oklcha {
fn from(value: Srgba) -> Self {
Oklaba::from(value).into()
}
}
impl From<Oklcha> for Srgba {
fn from(value: Oklcha) -> Self {
Oklaba::from(value).into()
}
}
impl From<Xyza> for Oklcha {
fn from(value: Xyza) -> Self {
Oklaba::from(value).into()
}
}
impl From<Oklcha> for Xyza {
fn from(value: Oklcha) -> Self {
Oklaba::from(value).into()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{test_colors::TEST_COLORS, testing::assert_approx_eq};
#[test]
fn test_to_from_srgba() {
let oklcha = Oklcha::new(0.5, 0.5, 180.0, 1.0);
let srgba: Srgba = oklcha.into();
let oklcha2: Oklcha = srgba.into();
assert_approx_eq!(oklcha.lightness, oklcha2.lightness, 0.001);
assert_approx_eq!(oklcha.chroma, oklcha2.chroma, 0.001);
assert_approx_eq!(oklcha.hue, oklcha2.hue, 0.001);
assert_approx_eq!(oklcha.alpha, oklcha2.alpha, 0.001);
}
#[test]
fn test_to_from_srgba_2() {
for color in TEST_COLORS.iter() {
let rgb2: Srgba = (color.oklch).into();
let oklch: Oklcha = (color.rgb).into();
assert!(
color.rgb.distance(&rgb2) < 0.0001,
"{}: {:?} != {:?}",
color.name,
color.rgb,
rgb2
);
assert!(
color.oklch.distance(&oklch) < 0.0001,
"{}: {:?} != {:?}",
color.name,
color.oklch,
oklch
);
}
}
#[test]
fn test_to_from_linear() {
let oklcha = Oklcha::new(0.5, 0.5, 0.5, 1.0);
let linear: LinearRgba = oklcha.into();
let oklcha2: Oklcha = linear.into();
assert_approx_eq!(oklcha.lightness, oklcha2.lightness, 0.001);
assert_approx_eq!(oklcha.chroma, oklcha2.chroma, 0.001);
assert_approx_eq!(oklcha.hue, oklcha2.hue, 0.001);
assert_approx_eq!(oklcha.alpha, oklcha2.alpha, 0.001);
}
}

39
vendor/bevy_color/src/palettes/basic.rs vendored Normal file
View File

@@ -0,0 +1,39 @@
//! Named colors from the CSS1 specification, also known as
//! [basic colors](https://en.wikipedia.org/wiki/Web_colors#Basic_colors).
//! This is the same set of colors used in the
//! [VGA graphics standard](https://en.wikipedia.org/wiki/Video_Graphics_Array).
use crate::Srgba;
/// <div style="background-color: #00FFFF; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AQUA: Srgba = Srgba::rgb(0.0, 1.0, 1.0);
/// <div style="background-color: #000000; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLACK: Srgba = Srgba::rgb(0.0, 0.0, 0.0);
/// <div style="background-color: #0000FF; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE: Srgba = Srgba::rgb(0.0, 0.0, 1.0);
/// <div style="background-color: #FF00FF; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA: Srgba = Srgba::rgb(1.0, 0.0, 1.0);
/// <div style="background-color: #808080; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY: Srgba = Srgba::rgb(0.5019608, 0.5019608, 0.5019608);
/// <div style="background-color: #008000; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN: Srgba = Srgba::rgb(0.0, 0.5019608, 0.0);
/// <div style="background-color: #00FF00; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME: Srgba = Srgba::rgb(0.0, 1.0, 0.0);
/// <div style="background-color: #800000; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MAROON: Srgba = Srgba::rgb(0.5019608, 0.0, 0.0);
/// <div style="background-color: #000080; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NAVY: Srgba = Srgba::rgb(0.0, 0.0, 0.5019608);
/// <div style="background-color: #808000; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const OLIVE: Srgba = Srgba::rgb(0.5019608, 0.5019608, 0.0);
/// <div style="background-color: #800080; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE: Srgba = Srgba::rgb(0.5019608, 0.0, 0.5019608);
/// <div style="background-color: #FF0000; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED: Srgba = Srgba::rgb(1.0, 0.0, 0.0);
/// <div style="background-color: #C0C0C0; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SILVER: Srgba = Srgba::rgb(0.7529412, 0.7529412, 0.7529412);
/// <div style="background-color: #008080; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL: Srgba = Srgba::rgb(0.0, 0.5019608, 0.5019608);
/// <div style="background-color: #FFFFFF; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const WHITE: Srgba = Srgba::rgb(1.0, 1.0, 1.0);
/// <div style="background-color: #FFFF00; width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW: Srgba = Srgba::rgb(1.0, 1.0, 0.0);

272
vendor/bevy_color/src/palettes/css.rs vendored Normal file
View File

@@ -0,0 +1,272 @@
//! [Extended colors from the CSS4 specification](https://en.wikipedia.org/wiki/Web_colors#Extended_colors),
//! Also known as X11 colors, which were standardized in HTML 4.0.
use crate::Srgba;
// The CSS4 colors are a superset of the CSS1 colors, so we can just re-export the CSS1 colors.
pub use crate::palettes::basic::*;
/// <div style="background-color:rgb(94.1%, 97.3%, 100.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ALICE_BLUE: Srgba = Srgba::new(0.941, 0.973, 1.0, 1.0);
/// <div style="background-color:rgb(98.0%, 92.2%, 84.3%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ANTIQUE_WHITE: Srgba = Srgba::new(0.98, 0.922, 0.843, 1.0);
/// <div style="background-color:rgb(0.0%, 100.0%, 100.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AQUA: Srgba = Srgba::new(0.0, 1.0, 1.0, 1.0);
/// <div style="background-color:rgb(49.8%, 100.0%, 83.1%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AQUAMARINE: Srgba = Srgba::new(0.498, 1.0, 0.831, 1.0);
/// <div style="background-color:rgb(94.1%, 100.0%, 100.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AZURE: Srgba = Srgba::new(0.941, 1.0, 1.0, 1.0);
/// <div style="background-color:rgb(96.1%, 96.1%, 86.3%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BEIGE: Srgba = Srgba::new(0.961, 0.961, 0.863, 1.0);
/// <div style="background-color:rgb(100.0%, 89.4%, 76.9%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BISQUE: Srgba = Srgba::new(1.0, 0.894, 0.769, 1.0);
/// <div style="background-color:rgb(100.0%, 92.2%, 80.4%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLANCHED_ALMOND: Srgba = Srgba::new(1.0, 0.922, 0.804, 1.0);
/// <div style="background-color:rgb(54.1%, 16.900000000000002%, 88.6%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_VIOLET: Srgba = Srgba::new(0.541, 0.169, 0.886, 1.0);
/// <div style="background-color:rgb(64.7%, 16.5%, 16.5%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BROWN: Srgba = Srgba::new(0.647, 0.165, 0.165, 1.0);
/// <div style="background-color:rgb(87.1%, 72.2%, 52.900000000000006%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BURLYWOOD: Srgba = Srgba::new(0.871, 0.722, 0.529, 1.0);
/// <div style="background-color:rgb(37.3%, 62.0%, 62.7%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CADET_BLUE: Srgba = Srgba::new(0.373, 0.62, 0.627, 1.0);
/// <div style="background-color:rgb(49.8%, 100.0%, 0.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CHARTREUSE: Srgba = Srgba::new(0.498, 1.0, 0.0, 1.0);
/// <div style="background-color:rgb(82.39999999999999%, 41.199999999999996%, 11.799999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CHOCOLATE: Srgba = Srgba::new(0.824, 0.412, 0.118, 1.0);
/// <div style="background-color:rgb(100.0%, 49.8%, 31.4%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CORAL: Srgba = Srgba::new(1.0, 0.498, 0.314, 1.0);
/// <div style="background-color:rgb(39.2%, 58.4%, 92.9%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CORNFLOWER_BLUE: Srgba = Srgba::new(0.392, 0.584, 0.929, 1.0);
/// <div style="background-color:rgb(100.0%, 97.3%, 86.3%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CORNSILK: Srgba = Srgba::new(1.0, 0.973, 0.863, 1.0);
/// <div style="background-color:rgb(86.3%, 7.8%, 23.5%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CRIMSON: Srgba = Srgba::new(0.863, 0.078, 0.235, 1.0);
/// <div style="background-color:rgb(0.0%, 0.0%, 54.50000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_BLUE: Srgba = Srgba::new(0.0, 0.0, 0.545, 1.0);
/// <div style="background-color:rgb(0.0%, 54.50000000000001%, 54.50000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_CYAN: Srgba = Srgba::new(0.0, 0.545, 0.545, 1.0);
/// <div style="background-color:rgb(72.2%, 52.5%, 4.3%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_GOLDENROD: Srgba = Srgba::new(0.722, 0.525, 0.043, 1.0);
/// <div style="background-color:rgb(66.3%, 66.3%, 66.3%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_GRAY: Srgba = Srgba::new(0.663, 0.663, 0.663, 1.0);
/// <div style="background-color:rgb(0.0%, 39.2%, 0.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_GREEN: Srgba = Srgba::new(0.0, 0.392, 0.0, 1.0);
/// <div style="background-color:rgb(66.3%, 66.3%, 66.3%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_GREY: Srgba = Srgba::new(0.663, 0.663, 0.663, 1.0);
/// <div style="background-color:rgb(74.1%, 71.8%, 42.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_KHAKI: Srgba = Srgba::new(0.741, 0.718, 0.42, 1.0);
/// <div style="background-color:rgb(54.50000000000001%, 0.0%, 54.50000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_MAGENTA: Srgba = Srgba::new(0.545, 0.0, 0.545, 1.0);
/// <div style="background-color:rgb(33.300000000000004%, 42.0%, 18.4%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_OLIVEGREEN: Srgba = Srgba::new(0.333, 0.42, 0.184, 1.0);
/// <div style="background-color:rgb(100.0%, 54.900000000000006%, 0.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_ORANGE: Srgba = Srgba::new(1.0, 0.549, 0.0, 1.0);
/// <div style="background-color:rgb(60.0%, 19.6%, 80.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_ORCHID: Srgba = Srgba::new(0.6, 0.196, 0.8, 1.0);
/// <div style="background-color:rgb(54.50000000000001%, 0.0%, 0.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_RED: Srgba = Srgba::new(0.545, 0.0, 0.0, 1.0);
/// <div style="background-color:rgb(91.4%, 58.8%, 47.8%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_SALMON: Srgba = Srgba::new(0.914, 0.588, 0.478, 1.0);
/// <div style="background-color:rgb(56.10000000000001%, 73.7%, 56.10000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_SEA_GREEN: Srgba = Srgba::new(0.561, 0.737, 0.561, 1.0);
/// <div style="background-color:rgb(28.199999999999996%, 23.9%, 54.50000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_SLATE_BLUE: Srgba = Srgba::new(0.282, 0.239, 0.545, 1.0);
/// <div style="background-color:rgb(18.4%, 31.0%, 31.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_SLATE_GRAY: Srgba = Srgba::new(0.184, 0.31, 0.31, 1.0);
/// <div style="background-color:rgb(18.4%, 31.0%, 31.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_SLATE_GREY: Srgba = Srgba::new(0.184, 0.31, 0.31, 1.0);
/// <div style="background-color:rgb(0.0%, 80.80000000000001%, 82.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_TURQUOISE: Srgba = Srgba::new(0.0, 0.808, 0.82, 1.0);
/// <div style="background-color:rgb(57.99999999999999%, 0.0%, 82.69999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DARK_VIOLET: Srgba = Srgba::new(0.58, 0.0, 0.827, 1.0);
/// <div style="background-color:rgb(100.0%, 7.8%, 57.599999999999994%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DEEP_PINK: Srgba = Srgba::new(1.0, 0.078, 0.576, 1.0);
/// <div style="background-color:rgb(0.0%, 74.9%, 100.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DEEP_SKY_BLUE: Srgba = Srgba::new(0.0, 0.749, 1.0, 1.0);
/// <div style="background-color:rgb(41.199999999999996%, 41.199999999999996%, 41.199999999999996%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DIM_GRAY: Srgba = Srgba::new(0.412, 0.412, 0.412, 1.0);
/// <div style="background-color:rgb(41.199999999999996%, 41.199999999999996%, 41.199999999999996%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DIM_GREY: Srgba = Srgba::new(0.412, 0.412, 0.412, 1.0);
/// <div style="background-color:rgb(11.799999999999999%, 56.49999999999999%, 100.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const DODGER_BLUE: Srgba = Srgba::new(0.118, 0.565, 1.0, 1.0);
/// <div style="background-color:rgb(69.8%, 13.3%, 13.3%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FIRE_BRICK: Srgba = Srgba::new(0.698, 0.133, 0.133, 1.0);
/// <div style="background-color:rgb(100.0%, 98.0%, 94.1%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FLORAL_WHITE: Srgba = Srgba::new(1.0, 0.98, 0.941, 1.0);
/// <div style="background-color:rgb(13.3%, 54.50000000000001%, 13.3%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FOREST_GREEN: Srgba = Srgba::new(0.133, 0.545, 0.133, 1.0);
/// <div style="background-color:rgb(86.3%, 86.3%, 86.3%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GAINSBORO: Srgba = Srgba::new(0.863, 0.863, 0.863, 1.0);
/// <div style="background-color:rgb(97.3%, 97.3%, 100.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GHOST_WHITE: Srgba = Srgba::new(0.973, 0.973, 1.0, 1.0);
/// <div style="background-color:rgb(100.0%, 84.3%, 0.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GOLD: Srgba = Srgba::new(1.0, 0.843, 0.0, 1.0);
/// <div style="background-color:rgb(85.5%, 64.7%, 12.5%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GOLDENROD: Srgba = Srgba::new(0.855, 0.647, 0.125, 1.0);
/// <div style="background-color:rgb(0.0%, 50.2%, 0.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_YELLOW: Srgba = Srgba::new(0.678, 1.0, 0.184, 1.0);
/// <div style="background-color:rgb(50.2%, 50.2%, 50.2%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREY: Srgba = Srgba::new(0.502, 0.502, 0.502, 1.0);
/// <div style="background-color:rgb(94.1%, 100.0%, 94.1%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const HONEYDEW: Srgba = Srgba::new(0.941, 1.0, 0.941, 1.0);
/// <div style="background-color:rgb(100.0%, 41.199999999999996%, 70.6%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const HOT_PINK: Srgba = Srgba::new(1.0, 0.412, 0.706, 1.0);
/// <div style="background-color:rgb(80.4%, 36.1%, 36.1%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIAN_RED: Srgba = Srgba::new(0.804, 0.361, 0.361, 1.0);
/// <div style="background-color:rgb(29.4%, 0.0%, 51.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO: Srgba = Srgba::new(0.294, 0.0, 0.51, 1.0);
/// <div style="background-color:rgb(100.0%, 100.0%, 94.1%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const IVORY: Srgba = Srgba::new(1.0, 1.0, 0.941, 1.0);
/// <div style="background-color:rgb(94.1%, 90.2%, 54.900000000000006%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const KHAKI: Srgba = Srgba::new(0.941, 0.902, 0.549, 1.0);
/// <div style="background-color:rgb(90.2%, 90.2%, 98.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LAVENDER: Srgba = Srgba::new(0.902, 0.902, 0.98, 1.0);
/// <div style="background-color:rgb(100.0%, 94.1%, 96.1%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LAVENDER_BLUSH: Srgba = Srgba::new(1.0, 0.941, 0.961, 1.0);
/// <div style="background-color:rgb(48.6%, 98.8%, 0.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LAWN_GREEN: Srgba = Srgba::new(0.486, 0.988, 0.0, 1.0);
/// <div style="background-color:rgb(100.0%, 98.0%, 80.4%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LEMON_CHIFFON: Srgba = Srgba::new(1.0, 0.98, 0.804, 1.0);
/// <div style="background-color:rgb(67.80000000000001%, 84.7%, 90.2%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_BLUE: Srgba = Srgba::new(0.678, 0.847, 0.902, 1.0);
/// <div style="background-color:rgb(94.1%, 50.2%, 50.2%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_CORAL: Srgba = Srgba::new(0.941, 0.502, 0.502, 1.0);
/// <div style="background-color:rgb(87.8%, 100.0%, 100.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_CYAN: Srgba = Srgba::new(0.878, 1.0, 1.0, 1.0);
/// <div style="background-color:rgb(98.0%, 98.0%, 82.39999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_GOLDENROD_YELLOW: Srgba = Srgba::new(0.98, 0.98, 0.824, 1.0);
/// <div style="background-color:rgb(82.69999999999999%, 82.69999999999999%, 82.69999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_GRAY: Srgba = Srgba::new(0.827, 0.827, 0.827, 1.0);
/// <div style="background-color:rgb(56.49999999999999%, 93.30000000000001%, 56.49999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_GREEN: Srgba = Srgba::new(0.565, 0.933, 0.565, 1.0);
/// <div style="background-color:rgb(82.69999999999999%, 82.69999999999999%, 82.69999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_GREY: Srgba = Srgba::new(0.827, 0.827, 0.827, 1.0);
/// <div style="background-color:rgb(100.0%, 71.39999999999999%, 75.7%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_PINK: Srgba = Srgba::new(1.0, 0.714, 0.757, 1.0);
/// <div style="background-color:rgb(100.0%, 62.7%, 47.8%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_SALMON: Srgba = Srgba::new(1.0, 0.627, 0.478, 1.0);
/// <div style="background-color:rgb(12.5%, 69.8%, 66.7%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_SEA_GREEN: Srgba = Srgba::new(0.125, 0.698, 0.667, 1.0);
/// <div style="background-color:rgb(52.900000000000006%, 80.80000000000001%, 98.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_SKY_BLUE: Srgba = Srgba::new(0.529, 0.808, 0.98, 1.0);
/// <div style="background-color:rgb(46.7%, 53.300000000000004%, 60.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_SLATE_GRAY: Srgba = Srgba::new(0.467, 0.533, 0.6, 1.0);
/// <div style="background-color:rgb(46.7%, 53.300000000000004%, 60.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_SLATE_GREY: Srgba = Srgba::new(0.467, 0.533, 0.6, 1.0);
/// <div style="background-color:rgb(69.0%, 76.9%, 87.1%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_STEEL_BLUE: Srgba = Srgba::new(0.69, 0.769, 0.871, 1.0);
/// <div style="background-color:rgb(100.0%, 100.0%, 87.8%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIGHT_YELLOW: Srgba = Srgba::new(1.0, 1.0, 0.878, 1.0);
/// <div style="background-color:rgb(19.6%, 80.4%, 19.6%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIMEGREEN: Srgba = Srgba::new(0.196, 0.804, 0.196, 1.0);
/// <div style="background-color:rgb(98.0%, 94.1%, 90.2%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LINEN: Srgba = Srgba::new(0.98, 0.941, 0.902, 1.0);
/// <div style="background-color:rgb(100.0%, 0.0%, 100.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MAGENTA: Srgba = Srgba::new(1.0, 0.0, 1.0, 1.0);
/// <div style="background-color:rgb(40.0%, 80.4%, 66.7%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MEDIUM_AQUAMARINE: Srgba = Srgba::new(0.4, 0.804, 0.667, 1.0);
/// <div style="background-color:rgb(0.0%, 0.0%, 80.4%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MEDIUM_BLUE: Srgba = Srgba::new(0.0, 0.0, 0.804, 1.0);
/// <div style="background-color:rgb(72.89999999999999%, 33.300000000000004%, 82.69999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MEDIUM_ORCHID: Srgba = Srgba::new(0.729, 0.333, 0.827, 1.0);
/// <div style="background-color:rgb(57.599999999999994%, 43.9%, 85.9%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MEDIUM_PURPLE: Srgba = Srgba::new(0.576, 0.439, 0.859, 1.0);
/// <div style="background-color:rgb(23.5%, 70.19999999999999%, 44.3%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MEDIUM_SEA_GREEN: Srgba = Srgba::new(0.235, 0.702, 0.443, 1.0);
/// <div style="background-color:rgb(48.199999999999996%, 40.8%, 93.30000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MEDIUM_SLATE_BLUE: Srgba = Srgba::new(0.482, 0.408, 0.933, 1.0);
/// <div style="background-color:rgb(0.0%, 98.0%, 60.4%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MEDIUM_SPRING_GREEN: Srgba = Srgba::new(0.0, 0.98, 0.604, 1.0);
/// <div style="background-color:rgb(28.199999999999996%, 82.0%, 80.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MEDIUM_TURQUOISE: Srgba = Srgba::new(0.282, 0.82, 0.8, 1.0);
/// <div style="background-color:rgb(78.0%, 8.200000000000001%, 52.2%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MEDIUM_VIOLET_RED: Srgba = Srgba::new(0.78, 0.082, 0.522, 1.0);
/// <div style="background-color:rgb(9.8%, 9.8%, 43.9%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MIDNIGHT_BLUE: Srgba = Srgba::new(0.098, 0.098, 0.439, 1.0);
/// <div style="background-color:rgb(96.1%, 100.0%, 98.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MINT_CREAM: Srgba = Srgba::new(0.961, 1.0, 0.98, 1.0);
/// <div style="background-color:rgb(100.0%, 89.4%, 88.2%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MISTY_ROSE: Srgba = Srgba::new(1.0, 0.894, 0.882, 1.0);
/// <div style="background-color:rgb(100.0%, 89.4%, 71.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const MOCCASIN: Srgba = Srgba::new(1.0, 0.894, 0.71, 1.0);
/// <div style="background-color:rgb(100.0%, 87.1%, 67.80000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NAVAJO_WHITE: Srgba = Srgba::new(1.0, 0.871, 0.678, 1.0);
/// <div style="background-color:rgb(99.2%, 96.1%, 90.2%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const OLD_LACE: Srgba = Srgba::new(0.992, 0.961, 0.902, 1.0);
/// <div style="background-color:rgb(42.0%, 55.7%, 13.700000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const OLIVE_DRAB: Srgba = Srgba::new(0.42, 0.557, 0.137, 1.0);
/// <div style="background-color:rgb(100.0%, 64.7%, 0.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE: Srgba = Srgba::new(1.0, 0.647, 0.0, 1.0);
/// <div style="background-color:rgb(100.0%, 27.1%, 0.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_RED: Srgba = Srgba::new(1.0, 0.271, 0.0, 1.0);
/// <div style="background-color:rgb(85.5%, 43.9%, 83.89999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORCHID: Srgba = Srgba::new(0.855, 0.439, 0.839, 1.0);
/// <div style="background-color:rgb(93.30000000000001%, 91.0%, 66.7%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PALE_GOLDENROD: Srgba = Srgba::new(0.933, 0.91, 0.667, 1.0);
/// <div style="background-color:rgb(59.599999999999994%, 98.4%, 59.599999999999994%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PALE_GREEN: Srgba = Srgba::new(0.596, 0.984, 0.596, 1.0);
/// <div style="background-color:rgb(68.60000000000001%, 93.30000000000001%, 93.30000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PALE_TURQUOISE: Srgba = Srgba::new(0.686, 0.933, 0.933, 1.0);
/// <div style="background-color:rgb(85.9%, 43.9%, 57.599999999999994%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PALE_VIOLETRED: Srgba = Srgba::new(0.859, 0.439, 0.576, 1.0);
/// <div style="background-color:rgb(100.0%, 93.7%, 83.5%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PAPAYA_WHIP: Srgba = Srgba::new(1.0, 0.937, 0.835, 1.0);
/// <div style="background-color:rgb(100.0%, 85.5%, 72.5%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PEACHPUFF: Srgba = Srgba::new(1.0, 0.855, 0.725, 1.0);
/// <div style="background-color:rgb(80.4%, 52.2%, 24.7%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PERU: Srgba = Srgba::new(0.804, 0.522, 0.247, 1.0);
/// <div style="background-color:rgb(100.0%, 75.3%, 79.60000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK: Srgba = Srgba::new(1.0, 0.753, 0.796, 1.0);
/// <div style="background-color:rgb(86.7%, 62.7%, 86.7%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PLUM: Srgba = Srgba::new(0.867, 0.627, 0.867, 1.0);
/// <div style="background-color:rgb(69.0%, 87.8%, 90.2%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const POWDER_BLUE: Srgba = Srgba::new(0.69, 0.878, 0.902, 1.0);
/// <div style="background-color:rgb(40.0%, 20.0%, 60.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const REBECCA_PURPLE: Srgba = Srgba::new(0.4, 0.2, 0.6, 1.0);
/// <div style="background-color:rgb(73.7%, 56.10000000000001%, 56.10000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSY_BROWN: Srgba = Srgba::new(0.737, 0.561, 0.561, 1.0);
/// <div style="background-color:rgb(25.5%, 41.199999999999996%, 88.2%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROYAL_BLUE: Srgba = Srgba::new(0.255, 0.412, 0.882, 1.0);
/// <div style="background-color:rgb(54.50000000000001%, 27.1%, 7.5%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SADDLE_BROWN: Srgba = Srgba::new(0.545, 0.271, 0.075, 1.0);
/// <div style="background-color:rgb(98.0%, 50.2%, 44.7%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SALMON: Srgba = Srgba::new(0.98, 0.502, 0.447, 1.0);
/// <div style="background-color:rgb(95.7%, 64.3%, 37.6%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SANDY_BROWN: Srgba = Srgba::new(0.957, 0.643, 0.376, 1.0);
/// <div style="background-color:rgb(18.0%, 54.50000000000001%, 34.1%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SEA_GREEN: Srgba = Srgba::new(0.18, 0.545, 0.341, 1.0);
/// <div style="background-color:rgb(100.0%, 96.1%, 93.30000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SEASHELL: Srgba = Srgba::new(1.0, 0.961, 0.933, 1.0);
/// <div style="background-color:rgb(62.7%, 32.2%, 17.599999999999998%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SIENNA: Srgba = Srgba::new(0.627, 0.322, 0.176, 1.0);
/// <div style="background-color:rgb(52.900000000000006%, 80.80000000000001%, 92.2%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_BLUE: Srgba = Srgba::new(0.529, 0.808, 0.922, 1.0);
/// <div style="background-color:rgb(41.6%, 35.3%, 80.4%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_BLUE: Srgba = Srgba::new(0.416, 0.353, 0.804, 1.0);
/// <div style="background-color:rgb(43.9%, 50.2%, 56.49999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_GRAY: Srgba = Srgba::new(0.439, 0.502, 0.565, 1.0);
/// <div style="background-color:rgb(43.9%, 50.2%, 56.49999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_GREY: Srgba = Srgba::new(0.439, 0.502, 0.565, 1.0);
/// <div style="background-color:rgb(100.0%, 98.0%, 98.0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SNOW: Srgba = Srgba::new(1.0, 0.98, 0.98, 1.0);
/// <div style="background-color:rgb(0.0%, 100.0%, 49.8%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SPRING_GREEN: Srgba = Srgba::new(0.0, 1.0, 0.498, 1.0);
/// <div style="background-color:rgb(27.500000000000004%, 51.0%, 70.6%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STEEL_BLUE: Srgba = Srgba::new(0.275, 0.51, 0.706, 1.0);
/// <div style="background-color:rgb(82.39999999999999%, 70.6%, 54.900000000000006%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TAN: Srgba = Srgba::new(0.824, 0.706, 0.549, 1.0);
/// <div style="background-color:rgb(84.7%, 74.9%, 84.7%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const THISTLE: Srgba = Srgba::new(0.847, 0.749, 0.847, 1.0);
/// <div style="background-color:rgb(100.0%, 38.800000000000004%, 27.800000000000004%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TOMATO: Srgba = Srgba::new(1.0, 0.388, 0.278, 1.0);
/// <div style="background-color:rgb(25.1%, 87.8%, 81.6%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TURQUOISE: Srgba = Srgba::new(0.251, 0.878, 0.816, 1.0);
/// <div style="background-color:rgb(93.30000000000001%, 51.0%, 93.30000000000001%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET: Srgba = Srgba::new(0.933, 0.51, 0.933, 1.0);
/// <div style="background-color:rgb(96.1%, 87.1%, 70.19999999999999%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const WHEAT: Srgba = Srgba::new(0.961, 0.871, 0.702, 1.0);
/// <div style="background-color:rgb(96.1%, 96.1%, 96.1%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const WHITE_SMOKE: Srgba = Srgba::new(0.961, 0.961, 0.961, 1.0);
/// <div style="background-color:rgb(60.4%, 80.4%, 19.6%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_GREEN: Srgba = Srgba::new(0.604, 0.804, 0.196, 1.0);

5
vendor/bevy_color/src/palettes/mod.rs vendored Normal file
View File

@@ -0,0 +1,5 @@
//! Color palettes consisting of collections of const colors.
pub mod basic;
pub mod css;
pub mod tailwind;

View File

@@ -0,0 +1,534 @@
//! Colors from [Tailwind CSS](https://tailwindcss.com/docs/customizing-colors) (MIT License).
//! Grouped by hue with numeric lightness scale (50 is light, 950 is dark).
//!
//! Generated from Tailwind 3.4.1.
// MIT License
//
// Copyright (c) Tailwind Labs, Inc.
//
// 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.
use crate::Srgba;
/// <div style="background-color:rgb(255, 251, 235); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_50: Srgba = Srgba::rgb(1.0, 0.9843137, 0.92156863);
/// <div style="background-color:rgb(254, 243, 199); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_100: Srgba = Srgba::rgb(0.99607843, 0.9529412, 0.78039217);
/// <div style="background-color:rgb(253, 230, 138); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_200: Srgba = Srgba::rgb(0.99215686, 0.9019608, 0.5411765);
/// <div style="background-color:rgb(252, 211, 77); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_300: Srgba = Srgba::rgb(0.9882353, 0.827451, 0.3019608);
/// <div style="background-color:rgb(251, 191, 36); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_400: Srgba = Srgba::rgb(0.9843137, 0.7490196, 0.14117648);
/// <div style="background-color:rgb(245, 158, 11); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_500: Srgba = Srgba::rgb(0.9607843, 0.61960787, 0.043137256);
/// <div style="background-color:rgb(217, 119, 6); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_600: Srgba = Srgba::rgb(0.8509804, 0.46666667, 0.023529412);
/// <div style="background-color:rgb(180, 83, 9); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_700: Srgba = Srgba::rgb(0.7058824, 0.3254902, 0.03529412);
/// <div style="background-color:rgb(146, 64, 14); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_800: Srgba = Srgba::rgb(0.57254905, 0.2509804, 0.05490196);
/// <div style="background-color:rgb(120, 53, 15); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_900: Srgba = Srgba::rgb(0.47058824, 0.20784314, 0.05882353);
/// <div style="background-color:rgb(69, 26, 3); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const AMBER_950: Srgba = Srgba::rgb(0.27058825, 0.101960786, 0.011764706);
/// <div style="background-color:rgb(239, 246, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_50: Srgba = Srgba::rgb(0.9372549, 0.9647059, 1.0);
/// <div style="background-color:rgb(219, 234, 254); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_100: Srgba = Srgba::rgb(0.85882354, 0.91764706, 0.99607843);
/// <div style="background-color:rgb(191, 219, 254); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_200: Srgba = Srgba::rgb(0.7490196, 0.85882354, 0.99607843);
/// <div style="background-color:rgb(147, 197, 253); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_300: Srgba = Srgba::rgb(0.5764706, 0.77254903, 0.99215686);
/// <div style="background-color:rgb(96, 165, 250); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_400: Srgba = Srgba::rgb(0.3764706, 0.64705884, 0.98039216);
/// <div style="background-color:rgb(59, 130, 246); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_500: Srgba = Srgba::rgb(0.23137255, 0.50980395, 0.9647059);
/// <div style="background-color:rgb(37, 99, 235); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_600: Srgba = Srgba::rgb(0.14509805, 0.3882353, 0.92156863);
/// <div style="background-color:rgb(29, 78, 216); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_700: Srgba = Srgba::rgb(0.11372549, 0.30588236, 0.84705883);
/// <div style="background-color:rgb(30, 64, 175); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_800: Srgba = Srgba::rgb(0.11764706, 0.2509804, 0.6862745);
/// <div style="background-color:rgb(30, 58, 138); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_900: Srgba = Srgba::rgb(0.11764706, 0.22745098, 0.5411765);
/// <div style="background-color:rgb(23, 37, 84); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLUE_950: Srgba = Srgba::rgb(0.09019608, 0.14509805, 0.32941177);
/// <div style="background-color:rgb(236, 254, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_50: Srgba = Srgba::rgb(0.9254902, 0.99607843, 1.0);
/// <div style="background-color:rgb(207, 250, 254); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_100: Srgba = Srgba::rgb(0.8117647, 0.98039216, 0.99607843);
/// <div style="background-color:rgb(165, 243, 252); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_200: Srgba = Srgba::rgb(0.64705884, 0.9529412, 0.9882353);
/// <div style="background-color:rgb(103, 232, 249); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_300: Srgba = Srgba::rgb(0.40392157, 0.9098039, 0.9764706);
/// <div style="background-color:rgb(34, 211, 238); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_400: Srgba = Srgba::rgb(0.13333334, 0.827451, 0.93333334);
/// <div style="background-color:rgb(6, 182, 212); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_500: Srgba = Srgba::rgb(0.023529412, 0.7137255, 0.83137256);
/// <div style="background-color:rgb(8, 145, 178); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_600: Srgba = Srgba::rgb(0.03137255, 0.5686275, 0.69803923);
/// <div style="background-color:rgb(14, 116, 144); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_700: Srgba = Srgba::rgb(0.05490196, 0.45490196, 0.5647059);
/// <div style="background-color:rgb(21, 94, 117); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_800: Srgba = Srgba::rgb(0.08235294, 0.36862746, 0.45882353);
/// <div style="background-color:rgb(22, 78, 99); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_900: Srgba = Srgba::rgb(0.08627451, 0.30588236, 0.3882353);
/// <div style="background-color:rgb(8, 51, 68); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const CYAN_950: Srgba = Srgba::rgb(0.03137255, 0.2, 0.26666668);
/// <div style="background-color:rgb(236, 253, 245); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_50: Srgba = Srgba::rgb(0.9254902, 0.99215686, 0.9607843);
/// <div style="background-color:rgb(209, 250, 229); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_100: Srgba = Srgba::rgb(0.81960785, 0.98039216, 0.8980392);
/// <div style="background-color:rgb(167, 243, 208); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_200: Srgba = Srgba::rgb(0.654902, 0.9529412, 0.8156863);
/// <div style="background-color:rgb(110, 231, 183); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_300: Srgba = Srgba::rgb(0.43137255, 0.90588236, 0.7176471);
/// <div style="background-color:rgb(52, 211, 153); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_400: Srgba = Srgba::rgb(0.20392157, 0.827451, 0.6);
/// <div style="background-color:rgb(16, 185, 129); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_500: Srgba = Srgba::rgb(0.0627451, 0.7254902, 0.5058824);
/// <div style="background-color:rgb(5, 150, 105); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_600: Srgba = Srgba::rgb(0.019607844, 0.5882353, 0.4117647);
/// <div style="background-color:rgb(4, 120, 87); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_700: Srgba = Srgba::rgb(0.015686275, 0.47058824, 0.34117648);
/// <div style="background-color:rgb(6, 95, 70); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_800: Srgba = Srgba::rgb(0.023529412, 0.37254903, 0.27450982);
/// <div style="background-color:rgb(6, 78, 59); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_900: Srgba = Srgba::rgb(0.023529412, 0.30588236, 0.23137255);
/// <div style="background-color:rgb(2, 44, 34); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const EMERALD_950: Srgba = Srgba::rgb(0.007843138, 0.17254902, 0.13333334);
/// <div style="background-color:rgb(253, 244, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_50: Srgba = Srgba::rgb(0.99215686, 0.95686275, 1.0);
/// <div style="background-color:rgb(250, 232, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_100: Srgba = Srgba::rgb(0.98039216, 0.9098039, 1.0);
/// <div style="background-color:rgb(245, 208, 254); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_200: Srgba = Srgba::rgb(0.9607843, 0.8156863, 0.99607843);
/// <div style="background-color:rgb(240, 171, 252); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_300: Srgba = Srgba::rgb(0.9411765, 0.67058825, 0.9882353);
/// <div style="background-color:rgb(232, 121, 249); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_400: Srgba = Srgba::rgb(0.9098039, 0.4745098, 0.9764706);
/// <div style="background-color:rgb(217, 70, 239); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_500: Srgba = Srgba::rgb(0.8509804, 0.27450982, 0.9372549);
/// <div style="background-color:rgb(192, 38, 211); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_600: Srgba = Srgba::rgb(0.7529412, 0.14901961, 0.827451);
/// <div style="background-color:rgb(162, 28, 175); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_700: Srgba = Srgba::rgb(0.63529414, 0.10980392, 0.6862745);
/// <div style="background-color:rgb(134, 25, 143); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_800: Srgba = Srgba::rgb(0.5254902, 0.09803922, 0.56078434);
/// <div style="background-color:rgb(112, 26, 117); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_900: Srgba = Srgba::rgb(0.4392157, 0.101960786, 0.45882353);
/// <div style="background-color:rgb(74, 4, 78); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const FUCHSIA_950: Srgba = Srgba::rgb(0.2901961, 0.015686275, 0.30588236);
/// <div style="background-color:rgb(249, 250, 251); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_50: Srgba = Srgba::rgb(0.9764706, 0.98039216, 0.9843137);
/// <div style="background-color:rgb(243, 244, 246); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_100: Srgba = Srgba::rgb(0.9529412, 0.95686275, 0.9647059);
/// <div style="background-color:rgb(229, 231, 235); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_200: Srgba = Srgba::rgb(0.8980392, 0.90588236, 0.92156863);
/// <div style="background-color:rgb(209, 213, 219); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_300: Srgba = Srgba::rgb(0.81960785, 0.8352941, 0.85882354);
/// <div style="background-color:rgb(156, 163, 175); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_400: Srgba = Srgba::rgb(0.6117647, 0.6392157, 0.6862745);
/// <div style="background-color:rgb(107, 114, 128); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_500: Srgba = Srgba::rgb(0.41960785, 0.44705883, 0.5019608);
/// <div style="background-color:rgb(75, 85, 99); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_600: Srgba = Srgba::rgb(0.29411766, 0.33333334, 0.3882353);
/// <div style="background-color:rgb(55, 65, 81); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_700: Srgba = Srgba::rgb(0.21568628, 0.25490198, 0.31764707);
/// <div style="background-color:rgb(31, 41, 55); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_800: Srgba = Srgba::rgb(0.12156863, 0.16078432, 0.21568628);
/// <div style="background-color:rgb(17, 24, 39); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_900: Srgba = Srgba::rgb(0.06666667, 0.09411765, 0.15294118);
/// <div style="background-color:rgb(3, 7, 18); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GRAY_950: Srgba = Srgba::rgb(0.011764706, 0.02745098, 0.07058824);
/// <div style="background-color:rgb(240, 253, 244); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_50: Srgba = Srgba::rgb(0.9411765, 0.99215686, 0.95686275);
/// <div style="background-color:rgb(220, 252, 231); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_100: Srgba = Srgba::rgb(0.8627451, 0.9882353, 0.90588236);
/// <div style="background-color:rgb(187, 247, 208); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_200: Srgba = Srgba::rgb(0.73333335, 0.96862745, 0.8156863);
/// <div style="background-color:rgb(134, 239, 172); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_300: Srgba = Srgba::rgb(0.5254902, 0.9372549, 0.6745098);
/// <div style="background-color:rgb(74, 222, 128); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_400: Srgba = Srgba::rgb(0.2901961, 0.87058824, 0.5019608);
/// <div style="background-color:rgb(34, 197, 94); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_500: Srgba = Srgba::rgb(0.13333334, 0.77254903, 0.36862746);
/// <div style="background-color:rgb(22, 163, 74); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_600: Srgba = Srgba::rgb(0.08627451, 0.6392157, 0.2901961);
/// <div style="background-color:rgb(21, 128, 61); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_700: Srgba = Srgba::rgb(0.08235294, 0.5019608, 0.23921569);
/// <div style="background-color:rgb(22, 101, 52); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_800: Srgba = Srgba::rgb(0.08627451, 0.39607844, 0.20392157);
/// <div style="background-color:rgb(20, 83, 45); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_900: Srgba = Srgba::rgb(0.078431375, 0.3254902, 0.1764706);
/// <div style="background-color:rgb(5, 46, 22); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const GREEN_950: Srgba = Srgba::rgb(0.019607844, 0.18039216, 0.08627451);
/// <div style="background-color:rgb(238, 242, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_50: Srgba = Srgba::rgb(0.93333334, 0.9490196, 1.0);
/// <div style="background-color:rgb(224, 231, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_100: Srgba = Srgba::rgb(0.8784314, 0.90588236, 1.0);
/// <div style="background-color:rgb(199, 210, 254); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_200: Srgba = Srgba::rgb(0.78039217, 0.8235294, 0.99607843);
/// <div style="background-color:rgb(165, 180, 252); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_300: Srgba = Srgba::rgb(0.64705884, 0.7058824, 0.9882353);
/// <div style="background-color:rgb(129, 140, 248); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_400: Srgba = Srgba::rgb(0.5058824, 0.54901963, 0.972549);
/// <div style="background-color:rgb(99, 102, 241); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_500: Srgba = Srgba::rgb(0.3882353, 0.4, 0.94509804);
/// <div style="background-color:rgb(79, 70, 229); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_600: Srgba = Srgba::rgb(0.30980393, 0.27450982, 0.8980392);
/// <div style="background-color:rgb(67, 56, 202); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_700: Srgba = Srgba::rgb(0.2627451, 0.21960784, 0.7921569);
/// <div style="background-color:rgb(55, 48, 163); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_800: Srgba = Srgba::rgb(0.21568628, 0.1882353, 0.6392157);
/// <div style="background-color:rgb(49, 46, 129); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_900: Srgba = Srgba::rgb(0.19215687, 0.18039216, 0.5058824);
/// <div style="background-color:rgb(30, 27, 75); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const INDIGO_950: Srgba = Srgba::rgb(0.11764706, 0.105882354, 0.29411766);
/// <div style="background-color:rgb(247, 254, 231); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_50: Srgba = Srgba::rgb(0.96862745, 0.99607843, 0.90588236);
/// <div style="background-color:rgb(236, 252, 203); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_100: Srgba = Srgba::rgb(0.9254902, 0.9882353, 0.79607844);
/// <div style="background-color:rgb(217, 249, 157); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_200: Srgba = Srgba::rgb(0.8509804, 0.9764706, 0.6156863);
/// <div style="background-color:rgb(190, 242, 100); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_300: Srgba = Srgba::rgb(0.74509805, 0.9490196, 0.39215687);
/// <div style="background-color:rgb(163, 230, 53); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_400: Srgba = Srgba::rgb(0.6392157, 0.9019608, 0.20784314);
/// <div style="background-color:rgb(132, 204, 22); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_500: Srgba = Srgba::rgb(0.5176471, 0.8, 0.08627451);
/// <div style="background-color:rgb(101, 163, 13); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_600: Srgba = Srgba::rgb(0.39607844, 0.6392157, 0.050980393);
/// <div style="background-color:rgb(77, 124, 15); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_700: Srgba = Srgba::rgb(0.3019608, 0.4862745, 0.05882353);
/// <div style="background-color:rgb(63, 98, 18); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_800: Srgba = Srgba::rgb(0.24705882, 0.38431373, 0.07058824);
/// <div style="background-color:rgb(54, 83, 20); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_900: Srgba = Srgba::rgb(0.21176471, 0.3254902, 0.078431375);
/// <div style="background-color:rgb(26, 46, 5); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const LIME_950: Srgba = Srgba::rgb(0.101960786, 0.18039216, 0.019607844);
/// <div style="background-color:rgb(250, 250, 250); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_50: Srgba = Srgba::rgb(0.98039216, 0.98039216, 0.98039216);
/// <div style="background-color:rgb(245, 245, 245); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_100: Srgba = Srgba::rgb(0.9607843, 0.9607843, 0.9607843);
/// <div style="background-color:rgb(229, 229, 229); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_200: Srgba = Srgba::rgb(0.8980392, 0.8980392, 0.8980392);
/// <div style="background-color:rgb(212, 212, 212); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_300: Srgba = Srgba::rgb(0.83137256, 0.83137256, 0.83137256);
/// <div style="background-color:rgb(163, 163, 163); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_400: Srgba = Srgba::rgb(0.6392157, 0.6392157, 0.6392157);
/// <div style="background-color:rgb(115, 115, 115); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_500: Srgba = Srgba::rgb(0.4509804, 0.4509804, 0.4509804);
/// <div style="background-color:rgb(82, 82, 82); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_600: Srgba = Srgba::rgb(0.32156864, 0.32156864, 0.32156864);
/// <div style="background-color:rgb(64, 64, 64); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_700: Srgba = Srgba::rgb(0.2509804, 0.2509804, 0.2509804);
/// <div style="background-color:rgb(38, 38, 38); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_800: Srgba = Srgba::rgb(0.14901961, 0.14901961, 0.14901961);
/// <div style="background-color:rgb(23, 23, 23); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_900: Srgba = Srgba::rgb(0.09019608, 0.09019608, 0.09019608);
/// <div style="background-color:rgb(10, 10, 10); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const NEUTRAL_950: Srgba = Srgba::rgb(0.039215688, 0.039215688, 0.039215688);
/// <div style="background-color:rgb(255, 247, 237); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_50: Srgba = Srgba::rgb(1.0, 0.96862745, 0.92941177);
/// <div style="background-color:rgb(255, 237, 213); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_100: Srgba = Srgba::rgb(1.0, 0.92941177, 0.8352941);
/// <div style="background-color:rgb(254, 215, 170); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_200: Srgba = Srgba::rgb(0.99607843, 0.84313726, 0.6666667);
/// <div style="background-color:rgb(253, 186, 116); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_300: Srgba = Srgba::rgb(0.99215686, 0.7294118, 0.45490196);
/// <div style="background-color:rgb(251, 146, 60); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_400: Srgba = Srgba::rgb(0.9843137, 0.57254905, 0.23529412);
/// <div style="background-color:rgb(249, 115, 22); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_500: Srgba = Srgba::rgb(0.9764706, 0.4509804, 0.08627451);
/// <div style="background-color:rgb(234, 88, 12); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_600: Srgba = Srgba::rgb(0.91764706, 0.34509805, 0.047058824);
/// <div style="background-color:rgb(194, 65, 12); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_700: Srgba = Srgba::rgb(0.7607843, 0.25490198, 0.047058824);
/// <div style="background-color:rgb(154, 52, 18); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_800: Srgba = Srgba::rgb(0.6039216, 0.20392157, 0.07058824);
/// <div style="background-color:rgb(124, 45, 18); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_900: Srgba = Srgba::rgb(0.4862745, 0.1764706, 0.07058824);
/// <div style="background-color:rgb(67, 20, 7); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ORANGE_950: Srgba = Srgba::rgb(0.2627451, 0.078431375, 0.02745098);
/// <div style="background-color:rgb(253, 242, 248); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_50: Srgba = Srgba::rgb(0.99215686, 0.9490196, 0.972549);
/// <div style="background-color:rgb(252, 231, 243); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_100: Srgba = Srgba::rgb(0.9882353, 0.90588236, 0.9529412);
/// <div style="background-color:rgb(251, 207, 232); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_200: Srgba = Srgba::rgb(0.9843137, 0.8117647, 0.9098039);
/// <div style="background-color:rgb(249, 168, 212); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_300: Srgba = Srgba::rgb(0.9764706, 0.65882355, 0.83137256);
/// <div style="background-color:rgb(244, 114, 182); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_400: Srgba = Srgba::rgb(0.95686275, 0.44705883, 0.7137255);
/// <div style="background-color:rgb(236, 72, 153); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_500: Srgba = Srgba::rgb(0.9254902, 0.28235295, 0.6);
/// <div style="background-color:rgb(219, 39, 119); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_600: Srgba = Srgba::rgb(0.85882354, 0.15294118, 0.46666667);
/// <div style="background-color:rgb(190, 24, 93); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_700: Srgba = Srgba::rgb(0.74509805, 0.09411765, 0.3647059);
/// <div style="background-color:rgb(157, 23, 77); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_800: Srgba = Srgba::rgb(0.6156863, 0.09019608, 0.3019608);
/// <div style="background-color:rgb(131, 24, 67); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_900: Srgba = Srgba::rgb(0.5137255, 0.09411765, 0.2627451);
/// <div style="background-color:rgb(80, 7, 36); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PINK_950: Srgba = Srgba::rgb(0.3137255, 0.02745098, 0.14117648);
/// <div style="background-color:rgb(250, 245, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_50: Srgba = Srgba::rgb(0.98039216, 0.9607843, 1.0);
/// <div style="background-color:rgb(243, 232, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_100: Srgba = Srgba::rgb(0.9529412, 0.9098039, 1.0);
/// <div style="background-color:rgb(233, 213, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_200: Srgba = Srgba::rgb(0.9137255, 0.8352941, 1.0);
/// <div style="background-color:rgb(216, 180, 254); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_300: Srgba = Srgba::rgb(0.84705883, 0.7058824, 0.99607843);
/// <div style="background-color:rgb(192, 132, 252); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_400: Srgba = Srgba::rgb(0.7529412, 0.5176471, 0.9882353);
/// <div style="background-color:rgb(168, 85, 247); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_500: Srgba = Srgba::rgb(0.65882355, 0.33333334, 0.96862745);
/// <div style="background-color:rgb(147, 51, 234); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_600: Srgba = Srgba::rgb(0.5764706, 0.2, 0.91764706);
/// <div style="background-color:rgb(126, 34, 206); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_700: Srgba = Srgba::rgb(0.49411765, 0.13333334, 0.80784315);
/// <div style="background-color:rgb(107, 33, 168); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_800: Srgba = Srgba::rgb(0.41960785, 0.12941177, 0.65882355);
/// <div style="background-color:rgb(88, 28, 135); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_900: Srgba = Srgba::rgb(0.34509805, 0.10980392, 0.5294118);
/// <div style="background-color:rgb(59, 7, 100); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const PURPLE_950: Srgba = Srgba::rgb(0.23137255, 0.02745098, 0.39215687);
/// <div style="background-color:rgb(254, 242, 242); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_50: Srgba = Srgba::rgb(0.99607843, 0.9490196, 0.9490196);
/// <div style="background-color:rgb(254, 226, 226); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_100: Srgba = Srgba::rgb(0.99607843, 0.8862745, 0.8862745);
/// <div style="background-color:rgb(254, 202, 202); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_200: Srgba = Srgba::rgb(0.99607843, 0.7921569, 0.7921569);
/// <div style="background-color:rgb(252, 165, 165); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_300: Srgba = Srgba::rgb(0.9882353, 0.64705884, 0.64705884);
/// <div style="background-color:rgb(248, 113, 113); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_400: Srgba = Srgba::rgb(0.972549, 0.44313726, 0.44313726);
/// <div style="background-color:rgb(239, 68, 68); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_500: Srgba = Srgba::rgb(0.9372549, 0.26666668, 0.26666668);
/// <div style="background-color:rgb(220, 38, 38); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_600: Srgba = Srgba::rgb(0.8627451, 0.14901961, 0.14901961);
/// <div style="background-color:rgb(185, 28, 28); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_700: Srgba = Srgba::rgb(0.7254902, 0.10980392, 0.10980392);
/// <div style="background-color:rgb(153, 27, 27); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_800: Srgba = Srgba::rgb(0.6, 0.105882354, 0.105882354);
/// <div style="background-color:rgb(127, 29, 29); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_900: Srgba = Srgba::rgb(0.49803922, 0.11372549, 0.11372549);
/// <div style="background-color:rgb(69, 10, 10); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const RED_950: Srgba = Srgba::rgb(0.27058825, 0.039215688, 0.039215688);
/// <div style="background-color:rgb(255, 241, 242); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_50: Srgba = Srgba::rgb(1.0, 0.94509804, 0.9490196);
/// <div style="background-color:rgb(255, 228, 230); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_100: Srgba = Srgba::rgb(1.0, 0.89411765, 0.9019608);
/// <div style="background-color:rgb(254, 205, 211); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_200: Srgba = Srgba::rgb(0.99607843, 0.8039216, 0.827451);
/// <div style="background-color:rgb(253, 164, 175); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_300: Srgba = Srgba::rgb(0.99215686, 0.6431373, 0.6862745);
/// <div style="background-color:rgb(251, 113, 133); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_400: Srgba = Srgba::rgb(0.9843137, 0.44313726, 0.52156866);
/// <div style="background-color:rgb(244, 63, 94); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_500: Srgba = Srgba::rgb(0.95686275, 0.24705882, 0.36862746);
/// <div style="background-color:rgb(225, 29, 72); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_600: Srgba = Srgba::rgb(0.88235295, 0.11372549, 0.28235295);
/// <div style="background-color:rgb(190, 18, 60); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_700: Srgba = Srgba::rgb(0.74509805, 0.07058824, 0.23529412);
/// <div style="background-color:rgb(159, 18, 57); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_800: Srgba = Srgba::rgb(0.62352943, 0.07058824, 0.22352941);
/// <div style="background-color:rgb(136, 19, 55); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_900: Srgba = Srgba::rgb(0.53333336, 0.07450981, 0.21568628);
/// <div style="background-color:rgb(76, 5, 25); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ROSE_950: Srgba = Srgba::rgb(0.29803923, 0.019607844, 0.09803922);
/// <div style="background-color:rgb(240, 249, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_50: Srgba = Srgba::rgb(0.9411765, 0.9764706, 1.0);
/// <div style="background-color:rgb(224, 242, 254); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_100: Srgba = Srgba::rgb(0.8784314, 0.9490196, 0.99607843);
/// <div style="background-color:rgb(186, 230, 253); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_200: Srgba = Srgba::rgb(0.7294118, 0.9019608, 0.99215686);
/// <div style="background-color:rgb(125, 211, 252); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_300: Srgba = Srgba::rgb(0.49019608, 0.827451, 0.9882353);
/// <div style="background-color:rgb(56, 189, 248); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_400: Srgba = Srgba::rgb(0.21960784, 0.7411765, 0.972549);
/// <div style="background-color:rgb(14, 165, 233); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_500: Srgba = Srgba::rgb(0.05490196, 0.64705884, 0.9137255);
/// <div style="background-color:rgb(2, 132, 199); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_600: Srgba = Srgba::rgb(0.007843138, 0.5176471, 0.78039217);
/// <div style="background-color:rgb(3, 105, 161); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_700: Srgba = Srgba::rgb(0.011764706, 0.4117647, 0.6313726);
/// <div style="background-color:rgb(7, 89, 133); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_800: Srgba = Srgba::rgb(0.02745098, 0.34901962, 0.52156866);
/// <div style="background-color:rgb(12, 74, 110); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_900: Srgba = Srgba::rgb(0.047058824, 0.2901961, 0.43137255);
/// <div style="background-color:rgb(8, 47, 73); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SKY_950: Srgba = Srgba::rgb(0.03137255, 0.18431373, 0.28627452);
/// <div style="background-color:rgb(248, 250, 252); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_50: Srgba = Srgba::rgb(0.972549, 0.98039216, 0.9882353);
/// <div style="background-color:rgb(241, 245, 249); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_100: Srgba = Srgba::rgb(0.94509804, 0.9607843, 0.9764706);
/// <div style="background-color:rgb(226, 232, 240); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_200: Srgba = Srgba::rgb(0.8862745, 0.9098039, 0.9411765);
/// <div style="background-color:rgb(203, 213, 225); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_300: Srgba = Srgba::rgb(0.79607844, 0.8352941, 0.88235295);
/// <div style="background-color:rgb(148, 163, 184); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_400: Srgba = Srgba::rgb(0.5803922, 0.6392157, 0.72156864);
/// <div style="background-color:rgb(100, 116, 139); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_500: Srgba = Srgba::rgb(0.39215687, 0.45490196, 0.54509807);
/// <div style="background-color:rgb(71, 85, 105); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_600: Srgba = Srgba::rgb(0.2784314, 0.33333334, 0.4117647);
/// <div style="background-color:rgb(51, 65, 85); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_700: Srgba = Srgba::rgb(0.2, 0.25490198, 0.33333334);
/// <div style="background-color:rgb(30, 41, 59); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_800: Srgba = Srgba::rgb(0.11764706, 0.16078432, 0.23137255);
/// <div style="background-color:rgb(15, 23, 42); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_900: Srgba = Srgba::rgb(0.05882353, 0.09019608, 0.16470589);
/// <div style="background-color:rgb(2, 6, 23); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const SLATE_950: Srgba = Srgba::rgb(0.007843138, 0.023529412, 0.09019608);
/// <div style="background-color:rgb(250, 250, 249); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_50: Srgba = Srgba::rgb(0.98039216, 0.98039216, 0.9764706);
/// <div style="background-color:rgb(245, 245, 244); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_100: Srgba = Srgba::rgb(0.9607843, 0.9607843, 0.95686275);
/// <div style="background-color:rgb(231, 229, 228); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_200: Srgba = Srgba::rgb(0.90588236, 0.8980392, 0.89411765);
/// <div style="background-color:rgb(214, 211, 209); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_300: Srgba = Srgba::rgb(0.8392157, 0.827451, 0.81960785);
/// <div style="background-color:rgb(168, 162, 158); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_400: Srgba = Srgba::rgb(0.65882355, 0.63529414, 0.61960787);
/// <div style="background-color:rgb(120, 113, 108); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_500: Srgba = Srgba::rgb(0.47058824, 0.44313726, 0.42352942);
/// <div style="background-color:rgb(87, 83, 78); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_600: Srgba = Srgba::rgb(0.34117648, 0.3254902, 0.30588236);
/// <div style="background-color:rgb(68, 64, 60); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_700: Srgba = Srgba::rgb(0.26666668, 0.2509804, 0.23529412);
/// <div style="background-color:rgb(41, 37, 36); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_800: Srgba = Srgba::rgb(0.16078432, 0.14509805, 0.14117648);
/// <div style="background-color:rgb(28, 25, 23); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_900: Srgba = Srgba::rgb(0.10980392, 0.09803922, 0.09019608);
/// <div style="background-color:rgb(12, 10, 9); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const STONE_950: Srgba = Srgba::rgb(0.047058824, 0.039215688, 0.03529412);
/// <div style="background-color:rgb(240, 253, 250); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_50: Srgba = Srgba::rgb(0.9411765, 0.99215686, 0.98039216);
/// <div style="background-color:rgb(204, 251, 241); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_100: Srgba = Srgba::rgb(0.8, 0.9843137, 0.94509804);
/// <div style="background-color:rgb(153, 246, 228); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_200: Srgba = Srgba::rgb(0.6, 0.9647059, 0.89411765);
/// <div style="background-color:rgb(94, 234, 212); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_300: Srgba = Srgba::rgb(0.36862746, 0.91764706, 0.83137256);
/// <div style="background-color:rgb(45, 212, 191); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_400: Srgba = Srgba::rgb(0.1764706, 0.83137256, 0.7490196);
/// <div style="background-color:rgb(20, 184, 166); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_500: Srgba = Srgba::rgb(0.078431375, 0.72156864, 0.6509804);
/// <div style="background-color:rgb(13, 148, 136); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_600: Srgba = Srgba::rgb(0.050980393, 0.5803922, 0.53333336);
/// <div style="background-color:rgb(15, 118, 110); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_700: Srgba = Srgba::rgb(0.05882353, 0.4627451, 0.43137255);
/// <div style="background-color:rgb(17, 94, 89); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_800: Srgba = Srgba::rgb(0.06666667, 0.36862746, 0.34901962);
/// <div style="background-color:rgb(19, 78, 74); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_900: Srgba = Srgba::rgb(0.07450981, 0.30588236, 0.2901961);
/// <div style="background-color:rgb(4, 47, 46); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const TEAL_950: Srgba = Srgba::rgb(0.015686275, 0.18431373, 0.18039216);
/// <div style="background-color:rgb(245, 243, 255); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_50: Srgba = Srgba::rgb(0.9607843, 0.9529412, 1.0);
/// <div style="background-color:rgb(237, 233, 254); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_100: Srgba = Srgba::rgb(0.92941177, 0.9137255, 0.99607843);
/// <div style="background-color:rgb(221, 214, 254); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_200: Srgba = Srgba::rgb(0.8666667, 0.8392157, 0.99607843);
/// <div style="background-color:rgb(196, 181, 253); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_300: Srgba = Srgba::rgb(0.76862746, 0.70980394, 0.99215686);
/// <div style="background-color:rgb(167, 139, 250); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_400: Srgba = Srgba::rgb(0.654902, 0.54509807, 0.98039216);
/// <div style="background-color:rgb(139, 92, 246); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_500: Srgba = Srgba::rgb(0.54509807, 0.36078432, 0.9647059);
/// <div style="background-color:rgb(124, 58, 237); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_600: Srgba = Srgba::rgb(0.4862745, 0.22745098, 0.92941177);
/// <div style="background-color:rgb(109, 40, 217); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_700: Srgba = Srgba::rgb(0.42745098, 0.15686275, 0.8509804);
/// <div style="background-color:rgb(91, 33, 182); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_800: Srgba = Srgba::rgb(0.35686275, 0.12941177, 0.7137255);
/// <div style="background-color:rgb(76, 29, 149); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_900: Srgba = Srgba::rgb(0.29803923, 0.11372549, 0.58431375);
/// <div style="background-color:rgb(46, 16, 101); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const VIOLET_950: Srgba = Srgba::rgb(0.18039216, 0.0627451, 0.39607844);
/// <div style="background-color:rgb(254, 252, 232); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_50: Srgba = Srgba::rgb(0.99607843, 0.9882353, 0.9098039);
/// <div style="background-color:rgb(254, 249, 195); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_100: Srgba = Srgba::rgb(0.99607843, 0.9764706, 0.7647059);
/// <div style="background-color:rgb(254, 240, 138); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_200: Srgba = Srgba::rgb(0.99607843, 0.9411765, 0.5411765);
/// <div style="background-color:rgb(253, 224, 71); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_300: Srgba = Srgba::rgb(0.99215686, 0.8784314, 0.2784314);
/// <div style="background-color:rgb(250, 204, 21); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_400: Srgba = Srgba::rgb(0.98039216, 0.8, 0.08235294);
/// <div style="background-color:rgb(234, 179, 8); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_500: Srgba = Srgba::rgb(0.91764706, 0.7019608, 0.03137255);
/// <div style="background-color:rgb(202, 138, 4); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_600: Srgba = Srgba::rgb(0.7921569, 0.5411765, 0.015686275);
/// <div style="background-color:rgb(161, 98, 7); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_700: Srgba = Srgba::rgb(0.6313726, 0.38431373, 0.02745098);
/// <div style="background-color:rgb(133, 77, 14); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_800: Srgba = Srgba::rgb(0.52156866, 0.3019608, 0.05490196);
/// <div style="background-color:rgb(113, 63, 18); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_900: Srgba = Srgba::rgb(0.44313726, 0.24705882, 0.07058824);
/// <div style="background-color:rgb(66, 32, 6); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const YELLOW_950: Srgba = Srgba::rgb(0.25882354, 0.1254902, 0.023529412);
/// <div style="background-color:rgb(250, 250, 250); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_50: Srgba = Srgba::rgb(0.98039216, 0.98039216, 0.98039216);
/// <div style="background-color:rgb(244, 244, 245); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_100: Srgba = Srgba::rgb(0.95686275, 0.95686275, 0.9607843);
/// <div style="background-color:rgb(228, 228, 231); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_200: Srgba = Srgba::rgb(0.89411765, 0.89411765, 0.90588236);
/// <div style="background-color:rgb(212, 212, 216); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_300: Srgba = Srgba::rgb(0.83137256, 0.83137256, 0.84705883);
/// <div style="background-color:rgb(161, 161, 170); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_400: Srgba = Srgba::rgb(0.6313726, 0.6313726, 0.6666667);
/// <div style="background-color:rgb(113, 113, 122); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_500: Srgba = Srgba::rgb(0.44313726, 0.44313726, 0.47843137);
/// <div style="background-color:rgb(82, 82, 91); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_600: Srgba = Srgba::rgb(0.32156864, 0.32156864, 0.35686275);
/// <div style="background-color:rgb(63, 63, 70); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_700: Srgba = Srgba::rgb(0.24705882, 0.24705882, 0.27450982);
/// <div style="background-color:rgb(39, 39, 42); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_800: Srgba = Srgba::rgb(0.15294118, 0.15294118, 0.16470589);
/// <div style="background-color:rgb(24, 24, 27); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_900: Srgba = Srgba::rgb(0.09411765, 0.09411765, 0.105882354);
/// <div style="background-color:rgb(9, 9, 11); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const ZINC_950: Srgba = Srgba::rgb(0.03529412, 0.03529412, 0.043137256);

521
vendor/bevy_color/src/srgba.rs vendored Normal file
View File

@@ -0,0 +1,521 @@
use crate::{
color_difference::EuclideanDistance, impl_componentwise_vector_space, Alpha, ColorToComponents,
ColorToPacked, Gray, LinearRgba, Luminance, Mix, StandardColor, Xyza,
};
#[cfg(feature = "alloc")]
use alloc::{format, string::String};
use bevy_math::{ops, Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
use thiserror::Error;
/// Non-linear standard RGB with alpha.
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct Srgba {
/// The red channel. [0.0, 1.0]
pub red: f32,
/// The green channel. [0.0, 1.0]
pub green: f32,
/// The blue channel. [0.0, 1.0]
pub blue: f32,
/// The alpha channel. [0.0, 1.0]
pub alpha: f32,
}
impl StandardColor for Srgba {}
impl_componentwise_vector_space!(Srgba, [red, green, blue, alpha]);
impl Srgba {
// The standard VGA colors, with alpha set to 1.0.
// https://en.wikipedia.org/wiki/Web_colors#Basic_colors
/// <div style="background-color:rgb(0%, 0%, 0%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const BLACK: Srgba = Srgba::new(0.0, 0.0, 0.0, 1.0);
/// <div style="background-color:rgba(0%, 0%, 0%, 0%); width: 10px; padding: 10px; border: 1px solid;"></div>
#[doc(alias = "transparent")]
pub const NONE: Srgba = Srgba::new(0.0, 0.0, 0.0, 0.0);
/// <div style="background-color:rgb(100%, 100%, 100%); width: 10px; padding: 10px; border: 1px solid;"></div>
pub const WHITE: Srgba = Srgba::new(1.0, 1.0, 1.0, 1.0);
/// A fully red color with full alpha.
pub const RED: Self = Self {
red: 1.0,
green: 0.0,
blue: 0.0,
alpha: 1.0,
};
/// A fully green color with full alpha.
pub const GREEN: Self = Self {
red: 0.0,
green: 1.0,
blue: 0.0,
alpha: 1.0,
};
/// A fully blue color with full alpha.
pub const BLUE: Self = Self {
red: 0.0,
green: 0.0,
blue: 1.0,
alpha: 1.0,
};
/// Construct a new [`Srgba`] color from components.
///
/// # Arguments
///
/// * `red` - Red channel. [0.0, 1.0]
/// * `green` - Green channel. [0.0, 1.0]
/// * `blue` - Blue channel. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn new(red: f32, green: f32, blue: f32, alpha: f32) -> Self {
Self {
red,
green,
blue,
alpha,
}
}
/// Construct a new [`Srgba`] color from (r, g, b) components, with the default alpha (1.0).
///
/// # Arguments
///
/// * `red` - Red channel. [0.0, 1.0]
/// * `green` - Green channel. [0.0, 1.0]
/// * `blue` - Blue channel. [0.0, 1.0]
pub const fn rgb(red: f32, green: f32, blue: f32) -> Self {
Self {
red,
green,
blue,
alpha: 1.0,
}
}
/// Return a copy of this color with the red channel set to the given value.
pub const fn with_red(self, red: f32) -> Self {
Self { red, ..self }
}
/// Return a copy of this color with the green channel set to the given value.
pub const fn with_green(self, green: f32) -> Self {
Self { green, ..self }
}
/// Return a copy of this color with the blue channel set to the given value.
pub const fn with_blue(self, blue: f32) -> Self {
Self { blue, ..self }
}
/// New `Srgba` from a CSS-style hexadecimal string.
///
/// # Examples
///
/// ```
/// # use bevy_color::Srgba;
/// let color = Srgba::hex("FF00FF").unwrap(); // fuchsia
/// let color = Srgba::hex("FF00FF7F").unwrap(); // partially transparent fuchsia
///
/// // A standard hex color notation is also available
/// assert_eq!(Srgba::hex("#FFFFFF").unwrap(), Srgba::new(1.0, 1.0, 1.0, 1.0));
/// ```
pub fn hex<T: AsRef<str>>(hex: T) -> Result<Self, HexColorError> {
let hex = hex.as_ref();
let hex = hex.strip_prefix('#').unwrap_or(hex);
match hex.len() {
// RGB
3 => {
let [l, b] = u16::from_str_radix(hex, 16)?.to_be_bytes();
let (r, g, b) = (l & 0x0F, (b & 0xF0) >> 4, b & 0x0F);
Ok(Self::rgb_u8((r << 4) | r, (g << 4) | g, (b << 4) | b))
}
// RGBA
4 => {
let [l, b] = u16::from_str_radix(hex, 16)?.to_be_bytes();
let (r, g, b, a) = ((l & 0xF0) >> 4, l & 0xF, (b & 0xF0) >> 4, b & 0x0F);
Ok(Self::rgba_u8(
(r << 4) | r,
(g << 4) | g,
(b << 4) | b,
(a << 4) | a,
))
}
// RRGGBB
6 => {
let [_, r, g, b] = u32::from_str_radix(hex, 16)?.to_be_bytes();
Ok(Self::rgb_u8(r, g, b))
}
// RRGGBBAA
8 => {
let [r, g, b, a] = u32::from_str_radix(hex, 16)?.to_be_bytes();
Ok(Self::rgba_u8(r, g, b, a))
}
_ => Err(HexColorError::Length),
}
}
/// Convert this color to CSS-style hexadecimal notation.
#[cfg(feature = "alloc")]
pub fn to_hex(&self) -> String {
let [r, g, b, a] = self.to_u8_array();
match a {
255 => format!("#{:02X}{:02X}{:02X}", r, g, b),
_ => format!("#{:02X}{:02X}{:02X}{:02X}", r, g, b, a),
}
}
/// New `Srgba` from sRGB colorspace.
///
/// # Arguments
///
/// * `r` - Red channel. [0, 255]
/// * `g` - Green channel. [0, 255]
/// * `b` - Blue channel. [0, 255]
///
/// See also [`Srgba::new`], [`Srgba::rgba_u8`], [`Srgba::hex`].
pub fn rgb_u8(r: u8, g: u8, b: u8) -> Self {
Self::from_u8_array_no_alpha([r, g, b])
}
// Float operations in const fn are not stable yet
// see https://github.com/rust-lang/rust/issues/57241
/// New `Srgba` from sRGB colorspace.
///
/// # Arguments
///
/// * `r` - Red channel. [0, 255]
/// * `g` - Green channel. [0, 255]
/// * `b` - Blue channel. [0, 255]
/// * `a` - Alpha channel. [0, 255]
///
/// See also [`Srgba::new`], [`Srgba::rgb_u8`], [`Srgba::hex`].
pub fn rgba_u8(r: u8, g: u8, b: u8, a: u8) -> Self {
Self::from_u8_array([r, g, b, a])
}
/// Converts a non-linear sRGB value to a linear one via [gamma correction](https://en.wikipedia.org/wiki/Gamma_correction).
pub fn gamma_function(value: f32) -> f32 {
if value <= 0.0 {
return value;
}
if value <= 0.04045 {
value / 12.92 // linear falloff in dark values
} else {
ops::powf((value + 0.055) / 1.055, 2.4) // gamma curve in other area
}
}
/// Converts a linear sRGB value to a non-linear one via [gamma correction](https://en.wikipedia.org/wiki/Gamma_correction).
pub fn gamma_function_inverse(value: f32) -> f32 {
if value <= 0.0 {
return value;
}
if value <= 0.0031308 {
value * 12.92 // linear falloff in dark values
} else {
(1.055 * ops::powf(value, 1.0 / 2.4)) - 0.055 // gamma curve in other area
}
}
}
impl Default for Srgba {
fn default() -> Self {
Self::WHITE
}
}
impl Luminance for Srgba {
#[inline]
fn luminance(&self) -> f32 {
let linear: LinearRgba = (*self).into();
linear.luminance()
}
#[inline]
fn with_luminance(&self, luminance: f32) -> Self {
let linear: LinearRgba = (*self).into();
linear
.with_luminance(Srgba::gamma_function(luminance))
.into()
}
#[inline]
fn darker(&self, amount: f32) -> Self {
let linear: LinearRgba = (*self).into();
linear.darker(amount).into()
}
#[inline]
fn lighter(&self, amount: f32) -> Self {
let linear: LinearRgba = (*self).into();
linear.lighter(amount).into()
}
}
impl Mix for Srgba {
#[inline]
fn mix(&self, other: &Self, factor: f32) -> Self {
let n_factor = 1.0 - factor;
Self {
red: self.red * n_factor + other.red * factor,
green: self.green * n_factor + other.green * factor,
blue: self.blue * n_factor + other.blue * factor,
alpha: self.alpha * n_factor + other.alpha * factor,
}
}
}
impl Alpha for Srgba {
#[inline]
fn with_alpha(&self, alpha: f32) -> Self {
Self { alpha, ..*self }
}
#[inline]
fn alpha(&self) -> f32 {
self.alpha
}
#[inline]
fn set_alpha(&mut self, alpha: f32) {
self.alpha = alpha;
}
}
impl EuclideanDistance for Srgba {
#[inline]
fn distance_squared(&self, other: &Self) -> f32 {
let dr = self.red - other.red;
let dg = self.green - other.green;
let db = self.blue - other.blue;
dr * dr + dg * dg + db * db
}
}
impl Gray for Srgba {
const BLACK: Self = Self::BLACK;
const WHITE: Self = Self::WHITE;
}
impl ColorToComponents for Srgba {
fn to_f32_array(self) -> [f32; 4] {
[self.red, self.green, self.blue, self.alpha]
}
fn to_f32_array_no_alpha(self) -> [f32; 3] {
[self.red, self.green, self.blue]
}
fn to_vec4(self) -> Vec4 {
Vec4::new(self.red, self.green, self.blue, self.alpha)
}
fn to_vec3(self) -> Vec3 {
Vec3::new(self.red, self.green, self.blue)
}
fn from_f32_array(color: [f32; 4]) -> Self {
Self {
red: color[0],
green: color[1],
blue: color[2],
alpha: color[3],
}
}
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self {
Self {
red: color[0],
green: color[1],
blue: color[2],
alpha: 1.0,
}
}
fn from_vec4(color: Vec4) -> Self {
Self {
red: color[0],
green: color[1],
blue: color[2],
alpha: color[3],
}
}
fn from_vec3(color: Vec3) -> Self {
Self {
red: color[0],
green: color[1],
blue: color[2],
alpha: 1.0,
}
}
}
impl ColorToPacked for Srgba {
fn to_u8_array(self) -> [u8; 4] {
[self.red, self.green, self.blue, self.alpha]
.map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
}
fn to_u8_array_no_alpha(self) -> [u8; 3] {
[self.red, self.green, self.blue].map(|v| ops::round(v.clamp(0.0, 1.0) * 255.0) as u8)
}
fn from_u8_array(color: [u8; 4]) -> Self {
Self::from_f32_array(color.map(|u| u as f32 / 255.0))
}
fn from_u8_array_no_alpha(color: [u8; 3]) -> Self {
Self::from_f32_array_no_alpha(color.map(|u| u as f32 / 255.0))
}
}
impl From<LinearRgba> for Srgba {
#[inline]
fn from(value: LinearRgba) -> Self {
Self {
red: Srgba::gamma_function_inverse(value.red),
green: Srgba::gamma_function_inverse(value.green),
blue: Srgba::gamma_function_inverse(value.blue),
alpha: value.alpha,
}
}
}
impl From<Srgba> for LinearRgba {
#[inline]
fn from(value: Srgba) -> Self {
Self {
red: Srgba::gamma_function(value.red),
green: Srgba::gamma_function(value.green),
blue: Srgba::gamma_function(value.blue),
alpha: value.alpha,
}
}
}
// Derived Conversions
impl From<Xyza> for Srgba {
fn from(value: Xyza) -> Self {
LinearRgba::from(value).into()
}
}
impl From<Srgba> for Xyza {
fn from(value: Srgba) -> Self {
LinearRgba::from(value).into()
}
}
/// Error returned if a hex string could not be parsed as a color.
#[derive(Debug, Error, PartialEq, Eq)]
pub enum HexColorError {
/// Parsing error.
#[error("Invalid hex string")]
Parse(#[from] core::num::ParseIntError),
/// Invalid length.
#[error("Unexpected length of hex string")]
Length,
/// Invalid character.
#[error("Invalid hex char")]
Char(char),
}
#[cfg(test)]
mod tests {
use crate::testing::assert_approx_eq;
use super::*;
#[test]
fn test_to_from_linear() {
let srgba = Srgba::new(0.0, 0.5, 1.0, 1.0);
let linear_rgba: LinearRgba = srgba.into();
assert_eq!(linear_rgba.red, 0.0);
assert_approx_eq!(linear_rgba.green, 0.2140, 0.0001);
assert_approx_eq!(linear_rgba.blue, 1.0, 0.0001);
assert_eq!(linear_rgba.alpha, 1.0);
let srgba2: Srgba = linear_rgba.into();
assert_eq!(srgba2.red, 0.0);
assert_approx_eq!(srgba2.green, 0.5, 0.0001);
assert_approx_eq!(srgba2.blue, 1.0, 0.0001);
assert_eq!(srgba2.alpha, 1.0);
}
#[test]
fn euclidean_distance() {
// White to black
let a = Srgba::new(0.0, 0.0, 0.0, 1.0);
let b = Srgba::new(1.0, 1.0, 1.0, 1.0);
assert_eq!(a.distance_squared(&b), 3.0);
// Alpha shouldn't matter
let a = Srgba::new(0.0, 0.0, 0.0, 1.0);
let b = Srgba::new(1.0, 1.0, 1.0, 0.0);
assert_eq!(a.distance_squared(&b), 3.0);
// Red to green
let a = Srgba::new(0.0, 0.0, 0.0, 1.0);
let b = Srgba::new(1.0, 0.0, 0.0, 1.0);
assert_eq!(a.distance_squared(&b), 1.0);
}
#[test]
fn darker_lighter() {
// Darker and lighter should be commutative.
let color = Srgba::new(0.4, 0.5, 0.6, 1.0);
let darker1 = color.darker(0.1);
let darker2 = darker1.darker(0.1);
let twice_as_dark = color.darker(0.2);
assert!(darker2.distance_squared(&twice_as_dark) < 0.0001);
let lighter1 = color.lighter(0.1);
let lighter2 = lighter1.lighter(0.1);
let twice_as_light = color.lighter(0.2);
assert!(lighter2.distance_squared(&twice_as_light) < 0.0001);
}
#[test]
fn hex_color() {
assert_eq!(Srgba::hex("FFF"), Ok(Srgba::WHITE));
assert_eq!(Srgba::hex("FFFF"), Ok(Srgba::WHITE));
assert_eq!(Srgba::hex("FFFFFF"), Ok(Srgba::WHITE));
assert_eq!(Srgba::hex("FFFFFFFF"), Ok(Srgba::WHITE));
assert_eq!(Srgba::hex("000"), Ok(Srgba::BLACK));
assert_eq!(Srgba::hex("000F"), Ok(Srgba::BLACK));
assert_eq!(Srgba::hex("000000"), Ok(Srgba::BLACK));
assert_eq!(Srgba::hex("000000FF"), Ok(Srgba::BLACK));
assert_eq!(Srgba::hex("03a9f4"), Ok(Srgba::rgb_u8(3, 169, 244)));
assert_eq!(Srgba::hex("yy"), Err(HexColorError::Length));
assert_eq!(Srgba::hex("#f2a"), Ok(Srgba::rgb_u8(255, 34, 170)));
assert_eq!(Srgba::hex("#e23030"), Ok(Srgba::rgb_u8(226, 48, 48)));
assert_eq!(Srgba::hex("#ff"), Err(HexColorError::Length));
assert_eq!(Srgba::hex("11223344"), Ok(Srgba::rgba_u8(17, 34, 51, 68)));
assert_eq!(Srgba::hex("1234"), Ok(Srgba::rgba_u8(17, 34, 51, 68)));
assert_eq!(Srgba::hex("12345678"), Ok(Srgba::rgba_u8(18, 52, 86, 120)));
assert_eq!(Srgba::hex("4321"), Ok(Srgba::rgba_u8(68, 51, 34, 17)));
assert!(matches!(Srgba::hex("yyy"), Err(HexColorError::Parse(_))));
assert!(matches!(Srgba::hex("##fff"), Err(HexColorError::Parse(_))));
}
}

275
vendor/bevy_color/src/test_colors.rs vendored Normal file
View File

@@ -0,0 +1,275 @@
// Generated by gen_tests. Do not edit.
#[cfg(test)]
use crate::{Hsla, Hsva, Hwba, Laba, Lcha, LinearRgba, Oklaba, Oklcha, Srgba, Xyza};
#[cfg(test)]
pub struct TestColor {
pub name: &'static str,
pub rgb: Srgba,
pub linear_rgb: LinearRgba,
pub hsl: Hsla,
pub hsv: Hsva,
pub hwb: Hwba,
pub lab: Laba,
pub lch: Lcha,
pub oklab: Oklaba,
pub oklch: Oklcha,
pub xyz: Xyza,
}
// Table of equivalent colors in various color spaces
#[cfg(test)]
pub const TEST_COLORS: &[TestColor] = &[
// black
TestColor {
name: "black",
rgb: Srgba::new(0.0, 0.0, 0.0, 1.0),
linear_rgb: LinearRgba::new(0.0, 0.0, 0.0, 1.0),
hsl: Hsla::new(0.0, 0.0, 0.0, 1.0),
lch: Lcha::new(0.0, 0.0, 0.0000136603785, 1.0),
hsv: Hsva::new(0.0, 0.0, 0.0, 1.0),
hwb: Hwba::new(0.0, 0.0, 1.0, 1.0),
lab: Laba::new(0.0, 0.0, 0.0, 1.0),
oklab: Oklaba::new(0.0, 0.0, 0.0, 1.0),
oklch: Oklcha::new(0.0, 0.0, 0.0, 1.0),
xyz: Xyza::new(0.0, 0.0, 0.0, 1.0),
},
// white
TestColor {
name: "white",
rgb: Srgba::new(1.0, 1.0, 1.0, 1.0),
linear_rgb: LinearRgba::new(1.0, 1.0, 1.0, 1.0),
hsl: Hsla::new(0.0, 0.0, 1.0, 1.0),
lch: Lcha::new(1.0, 0.0, 0.0000136603785, 1.0),
hsv: Hsva::new(0.0, 0.0, 1.0, 1.0),
hwb: Hwba::new(0.0, 1.0, 0.0, 1.0),
lab: Laba::new(1.0, 0.0, 0.0, 1.0),
oklab: Oklaba::new(1.0, 0.0, 0.000000059604645, 1.0),
oklch: Oklcha::new(1.0, 0.000000059604645, 90.0, 1.0),
xyz: Xyza::new(0.95047, 1.0, 1.08883, 1.0),
},
// red
TestColor {
name: "red",
rgb: Srgba::new(1.0, 0.0, 0.0, 1.0),
linear_rgb: LinearRgba::new(1.0, 0.0, 0.0, 1.0),
hsl: Hsla::new(0.0, 1.0, 0.5, 1.0),
lch: Lcha::new(0.53240794, 1.0455177, 39.99901, 1.0),
oklab: Oklaba::new(0.6279554, 0.22486295, 0.1258463, 1.0),
hsv: Hsva::new(0.0, 1.0, 1.0, 1.0),
hwb: Hwba::new(0.0, 0.0, 0.0, 1.0),
lab: Laba::new(0.532408, 0.8009243, 0.6720321, 1.0),
oklch: Oklcha::new(0.6279554, 0.2576833, 29.233892, 1.0),
xyz: Xyza::new(0.4124564, 0.2126729, 0.0193339, 1.0),
},
// green
TestColor {
name: "green",
rgb: Srgba::new(0.0, 1.0, 0.0, 1.0),
linear_rgb: LinearRgba::new(0.0, 1.0, 0.0, 1.0),
hsl: Hsla::new(120.0, 1.0, 0.5, 1.0),
lch: Lcha::new(0.87734723, 1.1977587, 136.01595, 1.0),
hsv: Hsva::new(120.0, 1.0, 1.0, 1.0),
hwb: Hwba::new(120.0, 0.0, 0.0, 1.0),
lab: Laba::new(0.8773472, -0.86182654, 0.8317931, 1.0),
oklab: Oklaba::new(0.8664396, -0.2338874, 0.1794985, 1.0),
oklch: Oklcha::new(0.8664396, 0.2948271, 142.49532, 1.0),
xyz: Xyza::new(0.3575761, 0.7151522, 0.119192, 1.0),
},
// blue
TestColor {
name: "blue",
rgb: Srgba::new(0.0, 0.0, 1.0, 1.0),
linear_rgb: LinearRgba::new(0.0, 0.0, 1.0, 1.0),
hsl: Hsla::new(240.0, 1.0, 0.5, 1.0),
lch: Lcha::new(0.32297012, 1.3380761, 306.28494, 1.0),
oklab: Oklaba::new(0.4520137, -0.032456964, -0.31152815, 1.0),
hsv: Hsva::new(240.0, 1.0, 1.0, 1.0),
hwb: Hwba::new(240.0, 0.0, 0.0, 1.0),
lab: Laba::new(0.32297015, 0.7918751, -1.0786015, 1.0),
oklch: Oklcha::new(0.45201376, 0.31321433, 264.05203, 1.0),
xyz: Xyza::new(0.1804375, 0.072175, 0.9503041, 1.0),
},
// yellow
TestColor {
name: "yellow",
rgb: Srgba::new(1.0, 1.0, 0.0, 1.0),
linear_rgb: LinearRgba::new(1.0, 1.0, 0.0, 1.0),
hsl: Hsla::new(60.0, 1.0, 0.5, 1.0),
lch: Lcha::new(0.9713927, 0.96905375, 102.85126, 1.0),
oklab: Oklaba::new(0.9679827, -0.07136908, 0.19856972, 1.0),
hsv: Hsva::new(60.0, 1.0, 1.0, 1.0),
hwb: Hwba::new(60.0, 0.0, 0.0, 1.0),
lab: Laba::new(0.9713927, -0.21553725, 0.94477975, 1.0),
oklch: Oklcha::new(0.9679827, 0.21100593, 109.76923, 1.0),
xyz: Xyza::new(0.7700325, 0.9278251, 0.1385259, 1.0),
},
// magenta
TestColor {
name: "magenta",
rgb: Srgba::new(1.0, 0.0, 1.0, 1.0),
linear_rgb: LinearRgba::new(1.0, 0.0, 1.0, 1.0),
hsl: Hsla::new(300.0, 1.0, 0.5, 1.0),
hsv: Hsva::new(300.0, 1.0, 1.0, 1.0),
hwb: Hwba::new(300.0, 0.0, 0.0, 1.0),
lab: Laba::new(0.6032421, 0.9823433, -0.60824895, 1.0),
lch: Lcha::new(0.6032421, 1.1554068, 328.23495, 1.0),
oklab: Oklaba::new(0.7016738, 0.27456632, -0.16915613, 1.0),
oklch: Oklcha::new(0.7016738, 0.32249108, 328.36343, 1.0),
xyz: Xyza::new(0.5928939, 0.28484792, 0.969638, 1.0),
},
// cyan
TestColor {
name: "cyan",
rgb: Srgba::new(0.0, 1.0, 1.0, 1.0),
linear_rgb: LinearRgba::new(0.0, 1.0, 1.0, 1.0),
hsl: Hsla::new(180.0, 1.0, 0.5, 1.0),
lch: Lcha::new(0.9111322, 0.50120866, 196.37614, 1.0),
oklab: Oklaba::new(0.90539926, -0.1494439, -0.039398134, 1.0),
hsv: Hsva::new(180.0, 1.0, 1.0, 1.0),
hwb: Hwba::new(180.0, 0.0, 0.0, 1.0),
lab: Laba::new(0.9111321, -0.4808751, -0.14131188, 1.0),
oklch: Oklcha::new(0.9053992, 0.15454963, 194.76901, 1.0),
xyz: Xyza::new(0.5380136, 0.78732723, 1.069496, 1.0),
},
// gray
TestColor {
name: "gray",
rgb: Srgba::new(0.5, 0.5, 0.5, 1.0),
linear_rgb: LinearRgba::new(0.21404114, 0.21404114, 0.21404114, 1.0),
hsl: Hsla::new(0.0, 0.0, 0.5, 1.0),
lch: Lcha::new(0.5338897, 0.00000011920929, 90.0, 1.0),
oklab: Oklaba::new(0.5981807, 0.00000011920929, 0.0, 1.0),
hsv: Hsva::new(0.0, 0.0, 0.5, 1.0),
hwb: Hwba::new(0.0, 0.5, 0.5, 1.0),
lab: Laba::new(0.5338897, 0.0, 0.0, 1.0),
oklch: Oklcha::new(0.5981808, 0.00000023841858, 0.0, 1.0),
xyz: Xyza::new(0.2034397, 0.21404117, 0.23305441, 1.0),
},
// olive
TestColor {
name: "olive",
rgb: Srgba::new(0.5, 0.5, 0.0, 1.0),
linear_rgb: LinearRgba::new(0.21404114, 0.21404114, 0.0, 1.0),
hsl: Hsla::new(60.0, 1.0, 0.25, 1.0),
lch: Lcha::new(0.51677734, 0.57966936, 102.851265, 1.0),
hsv: Hsva::new(60.0, 1.0, 0.5, 1.0),
hwb: Hwba::new(60.0, 0.0, 0.5, 1.0),
lab: Laba::new(0.51677734, -0.1289308, 0.5651491, 1.0),
oklab: Oklaba::new(0.57902855, -0.042691574, 0.11878061, 1.0),
oklch: Oklcha::new(0.57902855, 0.12621966, 109.76922, 1.0),
xyz: Xyza::new(0.16481864, 0.19859275, 0.029650241, 1.0),
},
// purple
TestColor {
name: "purple",
rgb: Srgba::new(0.5, 0.0, 0.5, 1.0),
linear_rgb: LinearRgba::new(0.21404114, 0.0, 0.21404114, 1.0),
hsl: Hsla::new(300.0, 1.0, 0.25, 1.0),
lch: Lcha::new(0.29655674, 0.69114214, 328.23495, 1.0),
hsv: Hsva::new(300.0, 1.0, 0.5, 1.0),
hwb: Hwba::new(300.0, 0.0, 0.5, 1.0),
lab: Laba::new(0.29655674, 0.58761847, -0.3638428, 1.0),
oklab: Oklaba::new(0.41972777, 0.1642403, -0.10118592, 1.0),
oklch: Oklcha::new(0.41972777, 0.19290791, 328.36343, 1.0),
xyz: Xyza::new(0.12690368, 0.060969174, 0.20754242, 1.0),
},
// teal
TestColor {
name: "teal",
rgb: Srgba::new(0.0, 0.5, 0.5, 1.0),
linear_rgb: LinearRgba::new(0.0, 0.21404114, 0.21404114, 1.0),
hsl: Hsla::new(180.0, 1.0, 0.25, 1.0),
lch: Lcha::new(0.48073065, 0.29981336, 196.37614, 1.0),
oklab: Oklaba::new(0.54159236, -0.08939436, -0.02356726, 1.0),
hsv: Hsva::new(180.0, 1.0, 0.5, 1.0),
hwb: Hwba::new(180.0, 0.0, 0.5, 1.0),
lab: Laba::new(0.4807306, -0.28765023, -0.084530115, 1.0),
oklch: Oklcha::new(0.54159236, 0.092448615, 194.76903, 1.0),
xyz: Xyza::new(0.11515705, 0.16852042, 0.22891617, 1.0),
},
// maroon
TestColor {
name: "maroon",
rgb: Srgba::new(0.5, 0.0, 0.0, 1.0),
linear_rgb: LinearRgba::new(0.21404114, 0.0, 0.0, 1.0),
hsl: Hsla::new(0.0, 1.0, 0.25, 1.0),
hsv: Hsva::new(0.0, 1.0, 0.5, 1.0),
hwb: Hwba::new(0.0, 0.0, 0.5, 1.0),
lab: Laba::new(0.2541851, 0.47909766, 0.37905872, 1.0),
lch: Lcha::new(0.2541851, 0.61091745, 38.350803, 1.0),
oklab: Oklaba::new(0.3756308, 0.13450874, 0.07527886, 1.0),
oklch: Oklcha::new(0.3756308, 0.1541412, 29.233906, 1.0),
xyz: Xyza::new(0.08828264, 0.045520753, 0.0041382504, 1.0),
},
// lime
TestColor {
name: "lime",
rgb: Srgba::new(0.0, 0.5, 0.0, 1.0),
linear_rgb: LinearRgba::new(0.0, 0.21404114, 0.0, 1.0),
hsl: Hsla::new(120.0, 1.0, 0.25, 1.0),
hsv: Hsva::new(120.0, 1.0, 0.5, 1.0),
hwb: Hwba::new(120.0, 0.0, 0.5, 1.0),
lab: Laba::new(0.46052113, -0.5155285, 0.4975627, 1.0),
lch: Lcha::new(0.46052113, 0.71647626, 136.01596, 1.0),
oklab: Oklaba::new(0.5182875, -0.13990697, 0.10737252, 1.0),
oklch: Oklcha::new(0.5182875, 0.17635989, 142.49535, 1.0),
xyz: Xyza::new(0.076536, 0.153072, 0.025511991, 1.0),
},
// navy
TestColor {
name: "navy",
rgb: Srgba::new(0.0, 0.0, 0.5, 1.0),
linear_rgb: LinearRgba::new(0.0, 0.0, 0.21404114, 1.0),
hsl: Hsla::new(240.0, 1.0, 0.25, 1.0),
lch: Lcha::new(0.12890343, 0.8004114, 306.28494, 1.0),
hsv: Hsva::new(240.0, 1.0, 0.5, 1.0),
hwb: Hwba::new(240.0, 0.0, 0.5, 1.0),
lab: Laba::new(0.12890343, 0.4736844, -0.64519864, 1.0),
oklab: Oklaba::new(0.27038592, -0.01941514, -0.18635012, 1.0),
oklch: Oklcha::new(0.27038592, 0.18735878, 264.05203, 1.0),
xyz: Xyza::new(0.03862105, 0.01544842, 0.20340417, 1.0),
},
// orange
TestColor {
name: "orange",
rgb: Srgba::new(0.5, 0.5, 0.0, 1.0),
linear_rgb: LinearRgba::new(0.21404114, 0.21404114, 0.0, 1.0),
hsl: Hsla::new(60.0, 1.0, 0.25, 1.0),
lch: Lcha::new(0.51677734, 0.57966936, 102.851265, 1.0),
hsv: Hsva::new(60.0, 1.0, 0.5, 1.0),
hwb: Hwba::new(60.0, 0.0, 0.5, 1.0),
lab: Laba::new(0.51677734, -0.1289308, 0.5651491, 1.0),
oklab: Oklaba::new(0.57902855, -0.042691574, 0.11878061, 1.0),
oklch: Oklcha::new(0.57902855, 0.12621966, 109.76922, 1.0),
xyz: Xyza::new(0.16481864, 0.19859275, 0.029650241, 1.0),
},
// fuchsia
TestColor {
name: "fuchsia",
rgb: Srgba::new(0.5, 0.0, 0.5, 1.0),
linear_rgb: LinearRgba::new(0.21404114, 0.0, 0.21404114, 1.0),
hsl: Hsla::new(300.0, 1.0, 0.25, 1.0),
lch: Lcha::new(0.29655674, 0.69114214, 328.23495, 1.0),
hsv: Hsva::new(300.0, 1.0, 0.5, 1.0),
hwb: Hwba::new(300.0, 0.0, 0.5, 1.0),
lab: Laba::new(0.29655674, 0.58761847, -0.3638428, 1.0),
oklab: Oklaba::new(0.41972777, 0.1642403, -0.10118592, 1.0),
oklch: Oklcha::new(0.41972777, 0.19290791, 328.36343, 1.0),
xyz: Xyza::new(0.12690368, 0.060969174, 0.20754242, 1.0),
},
// aqua
TestColor {
name: "aqua",
rgb: Srgba::new(0.0, 0.5, 0.5, 1.0),
linear_rgb: LinearRgba::new(0.0, 0.21404114, 0.21404114, 1.0),
hsl: Hsla::new(180.0, 1.0, 0.25, 1.0),
lch: Lcha::new(0.48073065, 0.29981336, 196.37614, 1.0),
oklab: Oklaba::new(0.54159236, -0.08939436, -0.02356726, 1.0),
hsv: Hsva::new(180.0, 1.0, 0.5, 1.0),
hwb: Hwba::new(180.0, 0.0, 0.5, 1.0),
lab: Laba::new(0.4807306, -0.28765023, -0.084530115, 1.0),
oklch: Oklcha::new(0.54159236, 0.092448615, 194.76903, 1.0),
xyz: Xyza::new(0.11515705, 0.16852042, 0.22891617, 1.0),
},
];

15
vendor/bevy_color/src/testing.rs vendored Normal file
View File

@@ -0,0 +1,15 @@
#[cfg(test)]
macro_rules! assert_approx_eq {
($x:expr, $y:expr, $d:expr) => {
if ($x - $y).abs() >= $d {
panic!(
"assertion failed: `(left !== right)` \
(left: `{}`, right: `{}`, tolerance: `{}`)",
$x, $y, $d
);
}
};
}
#[cfg(test)]
pub(crate) use assert_approx_eq;

285
vendor/bevy_color/src/xyza.rs vendored Normal file
View File

@@ -0,0 +1,285 @@
use crate::{
impl_componentwise_vector_space, Alpha, ColorToComponents, Gray, LinearRgba, Luminance, Mix,
StandardColor,
};
use bevy_math::{Vec3, Vec4};
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::prelude::*;
/// [CIE 1931](https://en.wikipedia.org/wiki/CIE_1931_color_space) color space, also known as XYZ, with an alpha channel.
#[doc = include_str!("../docs/conversion.md")]
/// <div>
#[doc = include_str!("../docs/diagrams/model_graph.svg")]
/// </div>
#[derive(Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
reflect(Clone, PartialEq, Default)
)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
all(feature = "serialize", feature = "bevy_reflect"),
reflect(Serialize, Deserialize)
)]
pub struct Xyza {
/// The x-axis. [0.0, 1.0]
pub x: f32,
/// The y-axis, intended to represent luminance. [0.0, 1.0]
pub y: f32,
/// The z-axis. [0.0, 1.0]
pub z: f32,
/// The alpha channel. [0.0, 1.0]
pub alpha: f32,
}
impl StandardColor for Xyza {}
impl_componentwise_vector_space!(Xyza, [x, y, z, alpha]);
impl Xyza {
/// Construct a new [`Xyza`] color from components.
///
/// # Arguments
///
/// * `x` - x-axis. [0.0, 1.0]
/// * `y` - y-axis. [0.0, 1.0]
/// * `z` - z-axis. [0.0, 1.0]
/// * `alpha` - Alpha channel. [0.0, 1.0]
pub const fn new(x: f32, y: f32, z: f32, alpha: f32) -> Self {
Self { x, y, z, alpha }
}
/// Construct a new [`Xyza`] color from (x, y, z) components, with the default alpha (1.0).
///
/// # Arguments
///
/// * `x` - x-axis. [0.0, 1.0]
/// * `y` - y-axis. [0.0, 1.0]
/// * `z` - z-axis. [0.0, 1.0]
pub const fn xyz(x: f32, y: f32, z: f32) -> Self {
Self {
x,
y,
z,
alpha: 1.0,
}
}
/// Return a copy of this color with the 'x' channel set to the given value.
pub const fn with_x(self, x: f32) -> Self {
Self { x, ..self }
}
/// Return a copy of this color with the 'y' channel set to the given value.
pub const fn with_y(self, y: f32) -> Self {
Self { y, ..self }
}
/// Return a copy of this color with the 'z' channel set to the given value.
pub const fn with_z(self, z: f32) -> Self {
Self { z, ..self }
}
/// [D65 White Point](https://en.wikipedia.org/wiki/Illuminant_D65#Definition)
pub const D65_WHITE: Self = Self::xyz(0.95047, 1.0, 1.08883);
}
impl Default for Xyza {
fn default() -> Self {
Self::new(0., 0., 0., 1.)
}
}
impl Alpha for Xyza {
#[inline]
fn with_alpha(&self, alpha: f32) -> Self {
Self { alpha, ..*self }
}
#[inline]
fn alpha(&self) -> f32 {
self.alpha
}
#[inline]
fn set_alpha(&mut self, alpha: f32) {
self.alpha = alpha;
}
}
impl Luminance for Xyza {
#[inline]
fn with_luminance(&self, lightness: f32) -> Self {
Self {
y: lightness,
..*self
}
}
fn luminance(&self) -> f32 {
self.y
}
fn darker(&self, amount: f32) -> Self {
Self {
y: (self.y - amount).clamp(0., 1.),
..*self
}
}
fn lighter(&self, amount: f32) -> Self {
Self {
y: (self.y + amount).min(1.),
..*self
}
}
}
impl Mix for Xyza {
#[inline]
fn mix(&self, other: &Self, factor: f32) -> Self {
let n_factor = 1.0 - factor;
Self {
x: self.x * n_factor + other.x * factor,
y: self.y * n_factor + other.y * factor,
z: self.z * n_factor + other.z * factor,
alpha: self.alpha * n_factor + other.alpha * factor,
}
}
}
impl Gray for Xyza {
const BLACK: Self = Self::new(0., 0., 0., 1.);
const WHITE: Self = Self::new(0.95047, 1.0, 1.08883, 1.0);
}
impl ColorToComponents for Xyza {
fn to_f32_array(self) -> [f32; 4] {
[self.x, self.y, self.z, self.alpha]
}
fn to_f32_array_no_alpha(self) -> [f32; 3] {
[self.x, self.y, self.z]
}
fn to_vec4(self) -> Vec4 {
Vec4::new(self.x, self.y, self.z, self.alpha)
}
fn to_vec3(self) -> Vec3 {
Vec3::new(self.x, self.y, self.z)
}
fn from_f32_array(color: [f32; 4]) -> Self {
Self {
x: color[0],
y: color[1],
z: color[2],
alpha: color[3],
}
}
fn from_f32_array_no_alpha(color: [f32; 3]) -> Self {
Self {
x: color[0],
y: color[1],
z: color[2],
alpha: 1.0,
}
}
fn from_vec4(color: Vec4) -> Self {
Self {
x: color[0],
y: color[1],
z: color[2],
alpha: color[3],
}
}
fn from_vec3(color: Vec3) -> Self {
Self {
x: color[0],
y: color[1],
z: color[2],
alpha: 1.0,
}
}
}
impl From<LinearRgba> for Xyza {
fn from(
LinearRgba {
red,
green,
blue,
alpha,
}: LinearRgba,
) -> Self {
// Linear sRGB to XYZ
// http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html (sRGB, RGB to XYZ [M])
let r = red;
let g = green;
let b = blue;
let x = r * 0.4124564 + g * 0.3575761 + b * 0.1804375;
let y = r * 0.2126729 + g * 0.7151522 + b * 0.072175;
let z = r * 0.0193339 + g * 0.119192 + b * 0.9503041;
Xyza::new(x, y, z, alpha)
}
}
impl From<Xyza> for LinearRgba {
fn from(Xyza { x, y, z, alpha }: Xyza) -> Self {
// XYZ to Linear sRGB
// http://www.brucelindbloom.com/index.html?Eqn_XYZ_to_RGB.html
// http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html (sRGB, XYZ to RGB [M]-1)
let r = x * 3.2404542 + y * -1.5371385 + z * -0.4985314;
let g = x * -0.969266 + y * 1.8760108 + z * 0.041556;
let b = x * 0.0556434 + y * -0.2040259 + z * 1.0572252;
LinearRgba::new(r, g, b, alpha)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{
color_difference::EuclideanDistance, test_colors::TEST_COLORS, testing::assert_approx_eq,
Srgba,
};
#[test]
fn test_to_from_srgba() {
let xyza = Xyza::new(0.5, 0.5, 0.5, 1.0);
let srgba: Srgba = xyza.into();
let xyza2: Xyza = srgba.into();
assert_approx_eq!(xyza.x, xyza2.x, 0.001);
assert_approx_eq!(xyza.y, xyza2.y, 0.001);
assert_approx_eq!(xyza.z, xyza2.z, 0.001);
assert_approx_eq!(xyza.alpha, xyza2.alpha, 0.001);
}
#[test]
fn test_to_from_srgba_2() {
for color in TEST_COLORS.iter() {
let rgb2: Srgba = (color.xyz).into();
let xyz2: Xyza = (color.rgb).into();
assert!(
color.rgb.distance(&rgb2) < 0.00001,
"{}: {:?} != {:?}",
color.name,
color.rgb,
rgb2
);
assert_approx_eq!(color.xyz.x, xyz2.x, 0.001);
assert_approx_eq!(color.xyz.y, xyz2.y, 0.001);
assert_approx_eq!(color.xyz.z, xyz2.z, 0.001);
assert_approx_eq!(color.xyz.alpha, xyz2.alpha, 0.001);
}
}
}