1#![allow(clippy::too_many_arguments)]
2use crate::{color::Argb, dynamic_color::DynamicScheme, palette::CorePalette, Map};
3#[cfg(not(feature = "std"))]
4use alloc::string::String;
5use core::{array::IntoIter, fmt};
6#[cfg(feature = "serde")]
7use serde::Serialize;
8#[cfg(feature = "std")]
9use std::string::String;
10
11pub mod variant;
12
13#[derive(Debug, PartialEq, Eq)]
14#[cfg_attr(feature = "serde", derive(Serialize))]
15pub struct Scheme {
16 pub primary: Argb,
17 pub on_primary: Argb,
18 pub primary_container: Argb,
19 pub on_primary_container: Argb,
20 pub inverse_primary: Argb,
21 pub primary_fixed: Argb,
22 pub primary_fixed_dim: Argb,
23 pub on_primary_fixed: Argb,
24 pub on_primary_fixed_variant: Argb,
25 pub secondary: Argb,
26 pub on_secondary: Argb,
27 pub secondary_container: Argb,
28 pub on_secondary_container: Argb,
29 pub secondary_fixed: Argb,
30 pub secondary_fixed_dim: Argb,
31 pub on_secondary_fixed: Argb,
32 pub on_secondary_fixed_variant: Argb,
33 pub tertiary: Argb,
34 pub on_tertiary: Argb,
35 pub tertiary_container: Argb,
36 pub on_tertiary_container: Argb,
37 pub tertiary_fixed: Argb,
38 pub tertiary_fixed_dim: Argb,
39 pub on_tertiary_fixed: Argb,
40 pub on_tertiary_fixed_variant: Argb,
41 pub error: Argb,
42 pub on_error: Argb,
43 pub error_container: Argb,
44 pub on_error_container: Argb,
45 pub surface_dim: Argb,
46 pub surface: Argb,
47 pub surface_tint: Argb,
48 pub surface_bright: Argb,
49 pub surface_container_lowest: Argb,
50 pub surface_container_low: Argb,
51 pub surface_container: Argb,
52 pub surface_container_high: Argb,
53 pub surface_container_highest: Argb,
54 pub on_surface: Argb,
55 pub on_surface_variant: Argb,
56 pub outline: Argb,
57 pub outline_variant: Argb,
58 pub inverse_surface: Argb,
59 pub inverse_on_surface: Argb,
60 pub surface_variant: Argb,
61 pub background: Argb,
62 pub on_background: Argb,
63 pub shadow: Argb,
64 pub scrim: Argb,
65}
66
67impl fmt::Display for Scheme {
68 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69 f.debug_struct("Scheme")
70 .field("primary", &self.primary)
71 .field("on_primary", &self.on_primary)
72 .field("primary_container", &self.primary_container)
73 .field("on_primary_container", &self.on_primary_container)
74 .field("inverse_primary", &self.inverse_primary)
75 .field("primary_fixed", &self.primary_fixed)
76 .field("primary_fixed_dim", &self.primary_fixed_dim)
77 .field("on_primary_fixed", &self.on_primary_fixed)
78 .field("on_primary_fixed_variant", &self.on_primary_fixed_variant)
79 .field("secondary", &self.secondary)
80 .field("on_secondary", &self.on_secondary)
81 .field("secondary_container", &self.secondary_container)
82 .field("on_secondary_container", &self.on_secondary_container)
83 .field("secondary_fixed", &self.secondary_fixed)
84 .field("secondary_fixed_dim", &self.secondary_fixed_dim)
85 .field("on_secondary_fixed", &self.on_secondary_fixed)
86 .field(
87 "on_secondary_fixed_variant",
88 &self.on_secondary_fixed_variant,
89 )
90 .field("tertiary", &self.tertiary)
91 .field("on_tertiary", &self.on_tertiary)
92 .field("tertiary_container", &self.tertiary_container)
93 .field("on_tertiary_container", &self.on_tertiary_container)
94 .field("tertiary_fixed", &self.tertiary_fixed)
95 .field("tertiary_fixed_dim", &self.tertiary_fixed_dim)
96 .field("on_tertiary_fixed", &self.on_tertiary_fixed)
97 .field("on_tertiary_fixed_variant", &self.on_tertiary_fixed_variant)
98 .field("error", &self.error)
99 .field("on_error", &self.on_error)
100 .field("error_container", &self.error_container)
101 .field("on_error_container", &self.on_error_container)
102 .field("surface_dim", &self.surface_dim)
103 .field("surface", &self.surface)
104 .field("surface_tint", &self.surface_tint)
105 .field("surface_bright", &self.surface_bright)
106 .field("surface_container_lowest", &self.surface_container_lowest)
107 .field("surface_container_low", &self.surface_container_low)
108 .field("surface_container", &self.surface_container)
109 .field("surface_container_high", &self.surface_container_high)
110 .field("surface_container_highest", &self.surface_container_highest)
111 .field("on_surface", &self.on_surface)
112 .field("on_surface_variant", &self.on_surface_variant)
113 .field("outline", &self.outline)
114 .field("outline_variant", &self.outline_variant)
115 .field("inverse_surface", &self.inverse_surface)
116 .field("inverse_on_surface", &self.inverse_on_surface)
117 .field("surface_variant", &self.surface_variant)
118 .field("background", &self.background)
119 .field("on_background", &self.on_background)
120 .field("shadow", &self.shadow)
121 .field("scrim", &self.scrim)
122 .finish()
123 }
124}
125
126impl Scheme {
127 pub const fn new(
128 primary: Argb,
129 on_primary: Argb,
130 primary_container: Argb,
131 on_primary_container: Argb,
132 inverse_primary: Argb,
133 primary_fixed: Argb,
134 primary_fixed_dim: Argb,
135 on_primary_fixed: Argb,
136 on_primary_fixed_variant: Argb,
137 secondary: Argb,
138 on_secondary: Argb,
139 secondary_container: Argb,
140 on_secondary_container: Argb,
141 secondary_fixed: Argb,
142 secondary_fixed_dim: Argb,
143 on_secondary_fixed: Argb,
144 on_secondary_fixed_variant: Argb,
145 tertiary: Argb,
146 on_tertiary: Argb,
147 tertiary_container: Argb,
148 on_tertiary_container: Argb,
149 tertiary_fixed: Argb,
150 tertiary_fixed_dim: Argb,
151 on_tertiary_fixed: Argb,
152 on_tertiary_fixed_variant: Argb,
153 error: Argb,
154 on_error: Argb,
155 error_container: Argb,
156 on_error_container: Argb,
157 surface_dim: Argb,
158 surface: Argb,
159 surface_tint: Argb,
160 surface_bright: Argb,
161 surface_container_lowest: Argb,
162 surface_container_low: Argb,
163 surface_container: Argb,
164 surface_container_high: Argb,
165 surface_container_highest: Argb,
166 on_surface: Argb,
167 on_surface_variant: Argb,
168 outline: Argb,
169 outline_variant: Argb,
170 inverse_surface: Argb,
171 inverse_on_surface: Argb,
172 surface_variant: Argb,
173 background: Argb,
174 on_background: Argb,
175 shadow: Argb,
176 scrim: Argb,
177 ) -> Self {
178 Self {
179 primary,
180 on_primary,
181 primary_container,
182 on_primary_container,
183 inverse_primary,
184 primary_fixed,
185 primary_fixed_dim,
186 on_primary_fixed,
187 on_primary_fixed_variant,
188 secondary,
189 on_secondary,
190 secondary_container,
191 on_secondary_container,
192 secondary_fixed,
193 secondary_fixed_dim,
194 on_secondary_fixed,
195 on_secondary_fixed_variant,
196 tertiary,
197 on_tertiary,
198 tertiary_container,
199 on_tertiary_container,
200 tertiary_fixed,
201 tertiary_fixed_dim,
202 on_tertiary_fixed,
203 on_tertiary_fixed_variant,
204 error,
205 on_error,
206 error_container,
207 on_error_container,
208 surface_dim,
209 surface,
210 surface_tint,
211 surface_bright,
212 surface_container_lowest,
213 surface_container_low,
214 surface_container,
215 surface_container_high,
216 surface_container_highest,
217 on_surface,
218 on_surface_variant,
219 outline,
220 outline_variant,
221 inverse_surface,
222 inverse_on_surface,
223 surface_variant,
224 background,
225 on_background,
226 shadow,
227 scrim,
228 }
229 }
230}
231
232impl From<DynamicScheme> for Scheme {
233 fn from(scheme: DynamicScheme) -> Self {
234 Self::new(
235 scheme.primary(),
236 scheme.on_primary(),
237 scheme.primary_container(),
238 scheme.on_primary_container(),
239 scheme.inverse_primary(),
240 scheme.primary_fixed(),
241 scheme.primary_fixed_dim(),
242 scheme.on_primary_fixed(),
243 scheme.on_primary_fixed_variant(),
244 scheme.secondary(),
245 scheme.on_secondary(),
246 scheme.secondary_container(),
247 scheme.on_secondary_container(),
248 scheme.secondary_fixed(),
249 scheme.secondary_fixed_dim(),
250 scheme.on_secondary_fixed(),
251 scheme.on_secondary_fixed_variant(),
252 scheme.tertiary(),
253 scheme.on_tertiary(),
254 scheme.tertiary_container(),
255 scheme.on_tertiary_container(),
256 scheme.tertiary_fixed(),
257 scheme.tertiary_fixed_dim(),
258 scheme.on_tertiary_fixed(),
259 scheme.on_tertiary_fixed_variant(),
260 scheme.error(),
261 scheme.on_error(),
262 scheme.error_container(),
263 scheme.on_error_container(),
264 scheme.surface_dim(),
265 scheme.surface(),
266 scheme.surface_tint(),
267 scheme.surface_bright(),
268 scheme.surface_container_lowest(),
269 scheme.surface_container_low(),
270 scheme.surface_container(),
271 scheme.surface_container_high(),
272 scheme.surface_container_highest(),
273 scheme.on_surface(),
274 scheme.on_surface_variant(),
275 scheme.outline(),
276 scheme.outline_variant(),
277 scheme.inverse_surface(),
278 scheme.inverse_on_surface(),
279 scheme.surface_variant(),
280 scheme.background(),
281 scheme.on_background(),
282 scheme.shadow(),
283 scheme.scrim(),
284 )
285 }
286}
287
288impl IntoIterator for Scheme {
289 type Item = (String, Argb);
290
291 type IntoIter = IntoIter<(String, Argb), 49>;
292
293 fn into_iter(self) -> Self::IntoIter {
294 [
295 ("primary".into(), self.primary),
296 ("on_primary".into(), self.on_primary),
297 ("primary_container".into(), self.primary_container),
298 ("on_primary_container".into(), self.on_primary_container),
299 ("inverse_primary".into(), self.inverse_primary),
300 ("primary_fixed".into(), self.primary_fixed),
301 ("primary_fixed_dim".into(), self.primary_fixed_dim),
302 ("on_primary_fixed".into(), self.on_primary_fixed),
303 (
304 "on_primary_fixed_variant".into(),
305 self.on_primary_fixed_variant,
306 ),
307 ("secondary".into(), self.secondary),
308 ("on_secondary".into(), self.on_secondary),
309 ("secondary_container".into(), self.secondary_container),
310 ("on_secondary_container".into(), self.on_secondary_container),
311 ("secondary_fixed".into(), self.secondary_fixed),
312 ("secondary_fixed_dim".into(), self.secondary_fixed_dim),
313 ("on_secondary_fixed".into(), self.on_secondary_fixed),
314 (
315 "on_secondary_fixed_variant".into(),
316 self.on_secondary_fixed_variant,
317 ),
318 ("tertiary".into(), self.tertiary),
319 ("on_tertiary".into(), self.on_tertiary),
320 ("tertiary_container".into(), self.tertiary_container),
321 ("on_tertiary_container".into(), self.on_tertiary_container),
322 ("tertiary_fixed".into(), self.tertiary_fixed),
323 ("tertiary_fixed_dim".into(), self.tertiary_fixed_dim),
324 ("on_tertiary_fixed".into(), self.on_tertiary_fixed),
325 (
326 "on_tertiary_fixed_variant".into(),
327 self.on_tertiary_fixed_variant,
328 ),
329 ("error".into(), self.error),
330 ("on_error".into(), self.on_error),
331 ("error_container".into(), self.error_container),
332 ("on_error_container".into(), self.on_error_container),
333 ("surface_dim".into(), self.surface_dim),
334 ("surface".into(), self.surface),
335 ("surface_tint".into(), self.surface_tint),
336 ("surface_bright".into(), self.surface_bright),
337 (
338 "surface_container_lowest".into(),
339 self.surface_container_lowest,
340 ),
341 ("surface_container_low".into(), self.surface_container_low),
342 ("surface_container".into(), self.surface_container),
343 ("surface_container_high".into(), self.surface_container_high),
344 (
345 "surface_container_highest".into(),
346 self.surface_container_highest,
347 ),
348 ("on_surface".into(), self.on_surface),
349 ("on_surface_variant".into(), self.on_surface_variant),
350 ("outline".into(), self.outline),
351 ("outline_variant".into(), self.outline_variant),
352 ("inverse_surface".into(), self.inverse_surface),
353 ("inverse_on_surface".into(), self.inverse_on_surface),
354 ("surface_variant".into(), self.surface_variant),
355 ("background".into(), self.background),
356 ("on_background".into(), self.on_background),
357 ("shadow".into(), self.shadow),
358 ("scrim".into(), self.scrim),
359 ]
360 .into_iter()
361 }
362}
363
364impl From<Scheme> for Map<String, String> {
365 fn from(value: Scheme) -> Self {
366 let map: Map<String, Argb> = Map::from_iter(value);
367
368 map.into_iter()
369 .map(|(key, value)| (key, value.to_hex_with_pound()))
370 .collect()
371 }
372}
373
374#[derive(PartialEq, Eq, Debug)]
378pub struct SchemeFromPalette {
379 pub primary: Argb,
380 pub on_primary: Argb,
381 pub primary_container: Argb,
382 pub on_primary_container: Argb,
383 pub secondary: Argb,
384 pub on_secondary: Argb,
385 pub secondary_container: Argb,
386 pub on_secondary_container: Argb,
387 pub tertiary: Argb,
388 pub on_tertiary: Argb,
389 pub tertiary_container: Argb,
390 pub on_tertiary_container: Argb,
391 pub error: Argb,
392 pub on_error: Argb,
393 pub error_container: Argb,
394 pub on_error_container: Argb,
395 pub surface: Argb,
396 pub on_surface: Argb,
397 pub surface_variant: Argb,
398 pub on_surface_variant: Argb,
399 pub outline: Argb,
400 pub outline_variant: Argb,
401 pub background: Argb,
402 pub on_background: Argb,
403 pub shadow: Argb,
404 pub scrim: Argb,
405 pub inverse_surface: Argb,
406 pub inverse_on_surface: Argb,
407 pub inverse_primary: Argb,
408}
409
410impl SchemeFromPalette {
411 pub fn light_from_palette(palette: &CorePalette) -> Self {
414 Self {
415 primary: palette.primary.tone(40),
416 on_primary: palette.primary.tone(100),
417 primary_container: palette.primary.tone(90),
418 on_primary_container: palette.primary.tone(10),
419 secondary: palette.secondary.tone(40),
420 on_secondary: palette.secondary.tone(100),
421 secondary_container: palette.secondary.tone(90),
422 on_secondary_container: palette.secondary.tone(10),
423 tertiary: palette.tertiary.tone(40),
424 on_tertiary: palette.tertiary.tone(100),
425 tertiary_container: palette.tertiary.tone(90),
426 on_tertiary_container: palette.tertiary.tone(10),
427 error: palette.error.tone(40),
428 on_error: palette.error.tone(100),
429 error_container: palette.error.tone(90),
430 on_error_container: palette.error.tone(10),
431 background: palette.neutral.tone(99),
432 on_background: palette.neutral.tone(10),
433 surface: palette.neutral.tone(99),
434 on_surface: palette.neutral.tone(10),
435 surface_variant: palette.neutral_variant.tone(90),
436 on_surface_variant: palette.neutral_variant.tone(30),
437 outline: palette.neutral_variant.tone(50),
438 outline_variant: palette.neutral_variant.tone(80),
439 shadow: palette.neutral.tone(0),
440 scrim: palette.neutral.tone(0),
441 inverse_surface: palette.neutral.tone(20),
442 inverse_on_surface: palette.neutral.tone(95),
443 inverse_primary: palette.primary.tone(80),
444 }
445 }
446
447 pub fn dark_from_palette(palette: &CorePalette) -> Self {
450 Self {
451 primary: palette.primary.tone(80),
452 on_primary: palette.primary.tone(20),
453 primary_container: palette.primary.tone(30),
454 on_primary_container: palette.primary.tone(90),
455 secondary: palette.secondary.tone(80),
456 on_secondary: palette.secondary.tone(20),
457 secondary_container: palette.secondary.tone(30),
458 on_secondary_container: palette.secondary.tone(90),
459 tertiary: palette.tertiary.tone(80),
460 on_tertiary: palette.tertiary.tone(20),
461 tertiary_container: palette.tertiary.tone(30),
462 on_tertiary_container: palette.tertiary.tone(90),
463 error: palette.error.tone(80),
464 on_error: palette.error.tone(20),
465 error_container: palette.error.tone(30),
466 on_error_container: palette.error.tone(80),
467 background: palette.neutral.tone(10),
468 on_background: palette.neutral.tone(90),
469 surface: palette.neutral.tone(10),
470 on_surface: palette.neutral.tone(90),
471 surface_variant: palette.neutral_variant.tone(30),
472 on_surface_variant: palette.neutral_variant.tone(80),
473 outline: palette.neutral_variant.tone(60),
474 outline_variant: palette.neutral_variant.tone(30),
475 shadow: palette.neutral.tone(0),
476 scrim: palette.neutral.tone(0),
477 inverse_surface: palette.neutral.tone(90),
478 inverse_on_surface: palette.neutral.tone(20),
479 inverse_primary: palette.primary.tone(40),
480 }
481 }
482
483 pub fn light(argb: Argb) -> Self {
484 Self::light_from_palette(&CorePalette::of(argb))
485 }
486
487 pub fn light_content(argb: Argb) -> Self {
488 Self::light_from_palette(&CorePalette::content_of(argb))
489 }
490
491 pub fn dark(argb: Argb) -> Self {
492 Self::dark_from_palette(&CorePalette::of(argb))
493 }
494
495 pub fn dark_content(argb: Argb) -> Self {
496 Self::dark_from_palette(&CorePalette::content_of(argb))
497 }
498}
499
500impl PartialEq<Scheme> for SchemeFromPalette {
501 fn eq(&self, other: &Scheme) -> bool {
502 self.primary == other.primary
503 && self.on_primary == other.on_primary
504 && self.primary_container == other.primary_container
505 && self.on_primary_container == other.on_primary_container
506 && self.secondary == other.secondary
507 && self.on_secondary == other.on_secondary
508 && self.secondary_container == other.secondary_container
509 && self.on_secondary_container == other.on_secondary_container
510 && self.tertiary == other.tertiary
511 && self.on_tertiary == other.on_tertiary
512 && self.tertiary_container == other.tertiary_container
513 && self.on_tertiary_container == other.on_tertiary_container
514 && self.error == other.error
515 && self.on_error == other.on_error
516 && self.error_container == other.error_container
517 && self.on_error_container == other.on_error_container
518 && self.surface == other.surface
519 && self.on_surface == other.on_surface
520 && self.surface_variant == other.surface_variant
521 && self.on_surface_variant == other.on_surface_variant
522 && self.outline == other.outline
523 && self.outline_variant == other.outline_variant
524 && self.background == other.background
525 && self.on_background == other.on_background
526 && self.shadow == other.shadow
527 && self.scrim == other.scrim
528 && self.inverse_surface == other.inverse_surface
529 && self.inverse_on_surface == other.inverse_on_surface
530 && self.inverse_primary == other.inverse_primary
531 }
532}
533
534#[cfg(test)]
535mod tests {
536 use crate::color::Argb;
537 use crate::scheme::SchemeFromPalette;
538 use float_cmp::assert_approx_eq;
539
540 #[test]
541 fn test_surface_tones() {
542 let c = Argb::from_u32(0xffff0000);
543
544 let light = SchemeFromPalette::light(c);
545 let dark = SchemeFromPalette::dark(c);
546
547 assert_approx_eq!(f64, light.surface.as_lstar(), 99.0, epsilon = 0.1); assert_approx_eq!(f64, dark.surface.as_lstar(), 10.0, epsilon = 0.1); }
550
551 #[test]
552 fn test_blue_scheme() {
553 let c = Argb::from_u32(0xff0000ff);
554
555 let light = SchemeFromPalette::light(c);
556 let dark = SchemeFromPalette::dark(c);
557
558 assert_eq!(light.primary.to_hex(), "343dff");
559 assert_eq!(dark.primary.to_hex(), "bec2ff");
560 }
561
562 #[test]
563 fn test_light_scheme_from_high_chroma_color() {
564 let c = Argb::from_u32(0xfffa2bec);
565
566 let scheme = SchemeFromPalette::light(c);
567
568 let expected = SchemeFromPalette {
569 primary: Argb::from_u32(0xffab00a2),
570 on_primary: Argb::from_u32(0xffffffff),
571 primary_container: Argb::from_u32(0xffffd7f3),
572 on_primary_container: Argb::from_u32(0xff390035),
573 secondary: Argb::from_u32(0xff6e5868),
574 on_secondary: Argb::from_u32(0xffffffff),
575 secondary_container: Argb::from_u32(0xfff8daee),
576 on_secondary_container: Argb::from_u32(0xff271624),
577 tertiary: Argb::from_u32(0xff815343),
578 on_tertiary: Argb::from_u32(0xffffffff),
579 tertiary_container: Argb::from_u32(0xffffdbd0),
580 on_tertiary_container: Argb::from_u32(0xff321207),
581 error: Argb::from_u32(0xffba1a1a),
582 on_error: Argb::from_u32(0xffffffff),
583 error_container: Argb::from_u32(0xffffdad6),
584 on_error_container: Argb::from_u32(0xff410002),
585 background: Argb::from_u32(0xfffffbff),
586 on_background: Argb::from_u32(0xff1f1a1d),
587 surface: Argb::from_u32(0xfffffbff),
588 on_surface: Argb::from_u32(0xff1f1a1d),
589 surface_variant: Argb::from_u32(0xffeedee7),
590 on_surface_variant: Argb::from_u32(0xff4e444b),
591 outline: Argb::from_u32(0xff80747b),
592 outline_variant: Argb::from_u32(0xffd2c2cb),
593 shadow: Argb::from_u32(0xff000000),
594 scrim: Argb::from_u32(0xff000000),
595 inverse_surface: Argb::from_u32(0xff342f32),
596 inverse_on_surface: Argb::from_u32(0xfff8eef2),
597 inverse_primary: Argb::from_u32(0xffffabee),
598 };
599
600 assert_eq!(scheme, expected);
601 }
602
603 #[test]
604 fn test_dark_scheme_from_high_chroma_color() {
605 let c = Argb::from_u32(0xfffa2bec);
606
607 let scheme = SchemeFromPalette::dark(c);
608
609 let expected = SchemeFromPalette {
610 primary: Argb::from_u32(0xffffabee),
611 on_primary: Argb::from_u32(0xff5c0057),
612 primary_container: Argb::from_u32(0xff83007b),
613 on_primary_container: Argb::from_u32(0xffffd7f3),
614 secondary: Argb::from_u32(0xffdbbed1),
615 on_secondary: Argb::from_u32(0xff3e2a39),
616 secondary_container: Argb::from_u32(0xff554050),
617 on_secondary_container: Argb::from_u32(0xfff8daee),
618 tertiary: Argb::from_u32(0xfff5b9a5),
619 on_tertiary: Argb::from_u32(0xff4c2619),
620 tertiary_container: Argb::from_u32(0xff663c2d),
621 on_tertiary_container: Argb::from_u32(0xffffdbd0),
622 error: Argb::from_u32(0xffffb4ab),
623 on_error: Argb::from_u32(0xff690005),
624 error_container: Argb::from_u32(0xff93000a),
625 on_error_container: Argb::from_u32(0xffffb4ab),
626 background: Argb::from_u32(0xff1f1a1d),
627 on_background: Argb::from_u32(0xffeae0e4),
628 surface: Argb::from_u32(0xff1f1a1d),
629 on_surface: Argb::from_u32(0xffeae0e4),
630 surface_variant: Argb::from_u32(0xff4e444b),
631 on_surface_variant: Argb::from_u32(0xffd2c2cb),
632 outline: Argb::from_u32(0xff9a8d95),
633 outline_variant: Argb::from_u32(0xff4e444b),
634 shadow: Argb::from_u32(0xff000000),
635 scrim: Argb::from_u32(0xff000000),
636 inverse_surface: Argb::from_u32(0xffeae0e4),
637 inverse_on_surface: Argb::from_u32(0xff342f32),
638 inverse_primary: Argb::from_u32(0xffab00a2),
639 };
640
641 assert_eq!(scheme, expected);
642 }
643
644 #[test]
645 fn test_light_content_scheme_from_high_chroma_color() {
646 let c = Argb::from_u32(0xfffa2bec);
647
648 let scheme = SchemeFromPalette::light_content(c);
649
650 let expected = SchemeFromPalette {
651 primary: Argb::from_u32(0xffab00a2),
652 on_primary: Argb::from_u32(0xffffffff),
653 primary_container: Argb::from_u32(0xffffd7f3),
654 on_primary_container: Argb::from_u32(0xff390035),
655 secondary: Argb::from_u32(0xff7f4e75),
656 on_secondary: Argb::from_u32(0xffffffff),
657 secondary_container: Argb::from_u32(0xffffd7f3),
658 on_secondary_container: Argb::from_u32(0xff330b2f),
659 tertiary: Argb::from_u32(0xff9c4323),
660 on_tertiary: Argb::from_u32(0xffffffff),
661 tertiary_container: Argb::from_u32(0xffffdbd0),
662 on_tertiary_container: Argb::from_u32(0xff390c00),
663 error: Argb::from_u32(0xffba1a1a),
664 on_error: Argb::from_u32(0xffffffff),
665 error_container: Argb::from_u32(0xffffdad6),
666 on_error_container: Argb::from_u32(0xff410002),
667 background: Argb::from_u32(0xfffffbff),
668 on_background: Argb::from_u32(0xff1f1a1d),
669 surface: Argb::from_u32(0xfffffbff),
670 on_surface: Argb::from_u32(0xff1f1a1d),
671 surface_variant: Argb::from_u32(0xffeedee7),
672 on_surface_variant: Argb::from_u32(0xff4e444b),
673 outline: Argb::from_u32(0xff80747b),
674 outline_variant: Argb::from_u32(0xffd2c2cb),
675 shadow: Argb::from_u32(0xff000000),
676 scrim: Argb::from_u32(0xff000000),
677 inverse_surface: Argb::from_u32(0xff342f32),
678 inverse_on_surface: Argb::from_u32(0xfff8eef2),
679 inverse_primary: Argb::from_u32(0xffffabee),
680 };
681
682 assert_eq!(scheme, expected);
683 }
684
685 #[test]
686 fn test_dark_content_scheme_from_high_chroma_color() {
687 let c = Argb::from_u32(0xfffa2bec);
688
689 let scheme = SchemeFromPalette::dark_content(c);
690
691 let expected = SchemeFromPalette {
692 primary: Argb::from_u32(0xffffabee),
693 on_primary: Argb::from_u32(0xff5c0057),
694 primary_container: Argb::from_u32(0xff83007b),
695 on_primary_container: Argb::from_u32(0xffffd7f3),
696 secondary: Argb::from_u32(0xfff0b4e1),
697 on_secondary: Argb::from_u32(0xff4b2145),
698 secondary_container: Argb::from_u32(0xff64375c),
699 on_secondary_container: Argb::from_u32(0xffffd7f3),
700 tertiary: Argb::from_u32(0xffffb59c),
701 on_tertiary: Argb::from_u32(0xff5c1900),
702 tertiary_container: Argb::from_u32(0xff7d2c0d),
703 on_tertiary_container: Argb::from_u32(0xffffdbd0),
704 error: Argb::from_u32(0xffffb4ab),
705 on_error: Argb::from_u32(0xff690005),
706 error_container: Argb::from_u32(0xff93000a),
707 on_error_container: Argb::from_u32(0xffffb4ab),
708 background: Argb::from_u32(0xff1f1a1d),
709 on_background: Argb::from_u32(0xffeae0e4),
710 surface: Argb::from_u32(0xff1f1a1d),
711 on_surface: Argb::from_u32(0xffeae0e4),
712 surface_variant: Argb::from_u32(0xff4e444b),
713 on_surface_variant: Argb::from_u32(0xffd2c2cb),
714 outline: Argb::from_u32(0xff9a8d95),
715 outline_variant: Argb::from_u32(0xff4e444b),
716 shadow: Argb::from_u32(0xff000000),
717 scrim: Argb::from_u32(0xff000000),
718 inverse_surface: Argb::from_u32(0xffeae0e4),
719 inverse_on_surface: Argb::from_u32(0xff342f32),
720 inverse_primary: Argb::from_u32(0xffab00a2),
721 };
722
723 assert_eq!(scheme, expected);
724 }
725}