CSSNumericType.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /*
  2. * Copyright (c) 2023-2024, Sam Atkins <sam@ladybird.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Array.h>
  8. #include <AK/Optional.h>
  9. #include <AK/String.h>
  10. #include <LibWeb/CSS/PropertyID.h>
  11. namespace Web::CSS {
  12. // https://drafts.css-houdini.org/css-typed-om-1/#numeric-typing
  13. // FIXME: Add IDL for this.
  14. class CSSNumericType {
  15. public:
  16. // https://drafts.css-houdini.org/css-typed-om-1/#cssnumericvalue-base-type
  17. enum class BaseType {
  18. Length,
  19. Angle,
  20. Time,
  21. Frequency,
  22. Resolution,
  23. Flex,
  24. Percent,
  25. __Count,
  26. };
  27. static Optional<BaseType> base_type_from_value_type(ValueType);
  28. static constexpr StringView base_type_name(BaseType base_type)
  29. {
  30. switch (base_type) {
  31. case BaseType::Length:
  32. return "length"sv;
  33. case BaseType::Angle:
  34. return "angle"sv;
  35. case BaseType::Time:
  36. return "time"sv;
  37. case BaseType::Frequency:
  38. return "frequency"sv;
  39. case BaseType::Resolution:
  40. return "resolution"sv;
  41. case BaseType::Flex:
  42. return "flex"sv;
  43. case BaseType::Percent:
  44. return "percent"sv;
  45. case BaseType::__Count:
  46. break;
  47. }
  48. VERIFY_NOT_REACHED();
  49. }
  50. static Optional<CSSNumericType> create_from_unit(StringView unit);
  51. CSSNumericType() = default;
  52. CSSNumericType(BaseType type, i32 power)
  53. {
  54. set_exponent(type, power);
  55. }
  56. Optional<CSSNumericType> added_to(CSSNumericType const& other) const;
  57. Optional<CSSNumericType> multiplied_by(CSSNumericType const& other) const;
  58. CSSNumericType inverted() const;
  59. bool has_consistent_type_with(CSSNumericType const& other) const;
  60. Optional<CSSNumericType> consistent_type(CSSNumericType const& other) const;
  61. Optional<CSSNumericType> made_consistent_with(CSSNumericType const& other) const;
  62. bool matches_angle() const { return matches_dimension(BaseType::Angle); }
  63. bool matches_angle_percentage() const { return matches_dimension_percentage(BaseType::Angle); }
  64. bool matches_flex() const { return matches_dimension(BaseType::Flex); }
  65. bool matches_frequency() const { return matches_dimension(BaseType::Frequency); }
  66. bool matches_frequency_percentage() const { return matches_dimension_percentage(BaseType::Frequency); }
  67. bool matches_length() const { return matches_dimension(BaseType::Length); }
  68. bool matches_length_percentage() const { return matches_dimension_percentage(BaseType::Length); }
  69. bool matches_number() const;
  70. bool matches_number_percentage() const;
  71. bool matches_percentage() const;
  72. bool matches_resolution() const { return matches_dimension(BaseType::Resolution); }
  73. bool matches_resolution_percentage() const { return matches_dimension_percentage(BaseType::Resolution); }
  74. bool matches_time() const { return matches_dimension(BaseType::Time); }
  75. bool matches_time_percentage() const { return matches_dimension_percentage(BaseType::Time); }
  76. bool matches_dimension() const;
  77. Optional<i32> const& exponent(BaseType type) const { return m_type_exponents[to_underlying(type)]; }
  78. void set_exponent(BaseType type, i32 exponent) { m_type_exponents[to_underlying(type)] = exponent; }
  79. Optional<BaseType> const& percent_hint() const { return m_percent_hint; }
  80. void set_percent_hint(Optional<BaseType> hint) { m_percent_hint = hint; }
  81. void apply_percent_hint(BaseType hint);
  82. bool operator==(CSSNumericType const& other) const = default;
  83. String dump() const;
  84. private:
  85. bool contains_all_the_non_zero_entries_of_other_with_the_same_value(CSSNumericType const& other) const;
  86. bool contains_a_key_other_than_percent_with_a_non_zero_value() const;
  87. enum class SkipIfAlreadyPresent {
  88. No,
  89. Yes,
  90. };
  91. void copy_all_entries_from(CSSNumericType const& other, SkipIfAlreadyPresent);
  92. Optional<BaseType> entry_with_value_1_while_all_others_are_0() const;
  93. bool matches_dimension(BaseType) const;
  94. bool matches_dimension_percentage(BaseType) const;
  95. Array<Optional<i32>, to_underlying(BaseType::__Count)> m_type_exponents;
  96. Optional<BaseType> m_percent_hint;
  97. };
  98. }
  99. template<>
  100. struct AK::Formatter<Web::CSS::CSSNumericType> : Formatter<StringView> {
  101. ErrorOr<void> format(FormatBuilder& builder, Web::CSS::CSSNumericType const& value)
  102. {
  103. return Formatter<StringView>::format(builder, value.dump());
  104. }
  105. };