PixelUnits.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /*
  2. * Copyright (c) 2023, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <AK/Math.h>
  7. #include <LibWeb/PixelUnits.h>
  8. namespace Web {
  9. CSSPixels::CSSPixels(int value)
  10. {
  11. m_value = value * fixed_point_denominator;
  12. }
  13. CSSPixels::CSSPixels(unsigned int value)
  14. {
  15. m_value = value * fixed_point_denominator;
  16. }
  17. CSSPixels::CSSPixels(unsigned long value)
  18. {
  19. m_value = value * fixed_point_denominator;
  20. }
  21. CSSPixels::CSSPixels(float value)
  22. {
  23. if (!isnan(value))
  24. m_value = AK::clamp_to_int(value * fixed_point_denominator);
  25. }
  26. CSSPixels::CSSPixels(double value)
  27. {
  28. if (!isnan(value))
  29. m_value = AK::clamp_to_int(value * fixed_point_denominator);
  30. }
  31. float CSSPixels::to_float() const
  32. {
  33. return static_cast<float>(m_value) / fixed_point_denominator;
  34. }
  35. double CSSPixels::to_double() const
  36. {
  37. return static_cast<double>(m_value) / fixed_point_denominator;
  38. }
  39. int CSSPixels::to_int() const
  40. {
  41. return m_value / fixed_point_denominator;
  42. }
  43. bool CSSPixels::might_be_saturated() const
  44. {
  45. return raw_value() == NumericLimits<i32>::max() || raw_value() == NumericLimits<i32>::min();
  46. }
  47. bool CSSPixels::operator==(CSSPixels const& other) const = default;
  48. CSSPixels& CSSPixels::operator++()
  49. {
  50. m_value = Checked<int>::saturating_add(m_value, fixed_point_denominator);
  51. return *this;
  52. }
  53. CSSPixels& CSSPixels::operator--()
  54. {
  55. m_value = Checked<int>::saturating_sub(m_value, fixed_point_denominator);
  56. return *this;
  57. }
  58. int CSSPixels::operator<=>(CSSPixels const& other) const
  59. {
  60. return raw_value() > other.raw_value() ? 1 : raw_value() < other.raw_value() ? -1
  61. : 0;
  62. }
  63. CSSPixels CSSPixels::operator+() const
  64. {
  65. return from_raw(+raw_value());
  66. }
  67. CSSPixels CSSPixels::operator-() const
  68. {
  69. return from_raw(-raw_value());
  70. }
  71. CSSPixels CSSPixels::operator+(CSSPixels const& other) const
  72. {
  73. return from_raw(Checked<int>::saturating_add(raw_value(), other.raw_value()));
  74. }
  75. CSSPixels CSSPixels::operator-(CSSPixels const& other) const
  76. {
  77. return from_raw(Checked<int>::saturating_sub(raw_value(), other.raw_value()));
  78. }
  79. CSSPixels CSSPixels::operator*(CSSPixels const& other) const
  80. {
  81. i64 value = raw_value();
  82. value *= other.raw_value();
  83. int int_value = AK::clamp_to_int(value >> fractional_bits);
  84. // Rounding:
  85. // If last bit cut off was 1:
  86. if (value & (1u << (fractional_bits - 1))) {
  87. // If the bit after was 1 as well
  88. if (value & (radix_mask >> 2u)) {
  89. // We need to round away from 0
  90. int_value = Checked<int>::saturating_add(int_value, 1);
  91. } else {
  92. // Otherwise we round to the next even value
  93. // Which means we add the least significant bit of the raw integer value
  94. int_value = Checked<int>::saturating_add(int_value, int_value & 1);
  95. }
  96. }
  97. return from_raw(int_value);
  98. }
  99. CSSPixels CSSPixels::operator/(CSSPixels const& other) const
  100. {
  101. i64 mult = raw_value();
  102. mult <<= fractional_bits;
  103. mult /= other.raw_value();
  104. int int_value = AK::clamp_to_int(mult);
  105. return from_raw(int_value);
  106. }
  107. CSSPixels& CSSPixels::operator+=(CSSPixels const& other)
  108. {
  109. *this = *this + other;
  110. return *this;
  111. }
  112. CSSPixels& CSSPixels::operator-=(CSSPixels const& other)
  113. {
  114. *this = *this - other;
  115. return *this;
  116. }
  117. CSSPixels& CSSPixels::operator*=(CSSPixels const& other)
  118. {
  119. *this = *this * other;
  120. return *this;
  121. }
  122. CSSPixels& CSSPixels::operator/=(CSSPixels const& other)
  123. {
  124. *this = *this / other;
  125. return *this;
  126. }
  127. CSSPixels CSSPixels::abs() const
  128. {
  129. return from_raw(::abs(m_value));
  130. }
  131. }