CSSColorValue.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
  3. * Copyright (c) 2021, Tobias Christiansen <tobyase@serenityos.org>
  4. * Copyright (c) 2021-2024, Sam Atkins <sam@ladybird.org>
  5. * Copyright (c) 2022-2023, MacDue <macdue@dueutil.tech>
  6. *
  7. * SPDX-License-Identifier: BSD-2-Clause
  8. */
  9. #include "CSSColorValue.h"
  10. #include <LibWeb/CSS/Serialize.h>
  11. #include <LibWeb/CSS/StyleValues/AngleStyleValue.h>
  12. #include <LibWeb/CSS/StyleValues/CSSMathValue.h>
  13. #include <LibWeb/CSS/StyleValues/CSSRGB.h>
  14. #include <LibWeb/CSS/StyleValues/NumberStyleValue.h>
  15. #include <LibWeb/CSS/StyleValues/PercentageStyleValue.h>
  16. namespace Web::CSS {
  17. ValueComparingNonnullRefPtr<CSSColorValue> CSSColorValue::create_from_color(Color color)
  18. {
  19. auto make_rgb_color = [](Color const& color) {
  20. return CSSRGB::create(
  21. NumberStyleValue::create(color.red()),
  22. NumberStyleValue::create(color.green()),
  23. NumberStyleValue::create(color.blue()),
  24. NumberStyleValue::create(color.alpha() / 255.0));
  25. };
  26. if (color.value() == 0) {
  27. static auto transparent = make_rgb_color(color);
  28. return transparent;
  29. }
  30. if (color == Color::from_rgb(0x000000)) {
  31. static auto black = make_rgb_color(color);
  32. return black;
  33. }
  34. if (color == Color::from_rgb(0xffffff)) {
  35. static auto white = make_rgb_color(color);
  36. return white;
  37. }
  38. return make_rgb_color(color);
  39. }
  40. Optional<float> CSSColorValue::resolve_hue(CSSStyleValue const& style_value)
  41. {
  42. // <number> | <angle> | none
  43. auto normalized = [](double number) {
  44. return fmod(number, 360.0);
  45. };
  46. if (style_value.is_number())
  47. return normalized(style_value.as_number().number());
  48. if (style_value.is_angle())
  49. return normalized(style_value.as_angle().angle().to_degrees());
  50. if (style_value.is_math() && style_value.as_math().resolves_to_angle())
  51. return normalized(style_value.as_math().resolve_angle().value().to_degrees());
  52. if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None)
  53. return 0;
  54. return {};
  55. }
  56. Optional<float> CSSColorValue::resolve_with_reference_value(CSSStyleValue const& style_value, float one_hundred_percent_value)
  57. {
  58. // <percentage> | <number> | none
  59. auto normalize_percentage = [one_hundred_percent_value](Percentage const& percentage) {
  60. return static_cast<float>(percentage.as_fraction()) * one_hundred_percent_value;
  61. };
  62. if (style_value.is_percentage())
  63. return normalize_percentage(style_value.as_percentage().percentage());
  64. if (style_value.is_number())
  65. return style_value.as_number().number();
  66. if (style_value.is_math()) {
  67. auto const& calculated = style_value.as_math();
  68. if (calculated.resolves_to_number())
  69. return calculated.resolve_number().value();
  70. if (calculated.resolves_to_percentage())
  71. return normalize_percentage(calculated.resolve_percentage().value());
  72. }
  73. if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None)
  74. return 0;
  75. return {};
  76. }
  77. Optional<float> CSSColorValue::resolve_alpha(CSSStyleValue const& style_value)
  78. {
  79. // <number> | <percentage> | none
  80. auto normalized = [](double number) {
  81. return clamp(number, 0.0, 1.0);
  82. };
  83. if (style_value.is_number())
  84. return normalized(style_value.as_number().number());
  85. if (style_value.is_percentage())
  86. return normalized(style_value.as_percentage().percentage().as_fraction());
  87. if (style_value.is_math()) {
  88. auto const& calculated = style_value.as_math();
  89. if (calculated.resolves_to_number())
  90. return normalized(calculated.resolve_number().value());
  91. if (calculated.resolves_to_percentage())
  92. return normalized(calculated.resolve_percentage().value().as_fraction());
  93. }
  94. if (style_value.is_keyword() && style_value.to_keyword() == Keyword::None)
  95. return 0;
  96. return {};
  97. }
  98. }