PixelUnits.cpp 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. static i32 const fractional_bits = 6;
  10. static constexpr i32 fixed_point_denominator = 1 << fractional_bits;
  11. CSSPixels::CSSPixels(int value)
  12. {
  13. m_value = value * fixed_point_denominator;
  14. }
  15. CSSPixels::CSSPixels(unsigned int value)
  16. {
  17. m_value = value * fixed_point_denominator;
  18. }
  19. CSSPixels::CSSPixels(unsigned long value)
  20. {
  21. m_value = value * fixed_point_denominator;
  22. }
  23. CSSPixels::CSSPixels(float value)
  24. {
  25. if (!isnan(value))
  26. m_value = AK::clamp_to_int(value * fixed_point_denominator);
  27. }
  28. CSSPixels::CSSPixels(double value)
  29. {
  30. if (!isnan(value))
  31. m_value = AK::clamp_to_int(value * fixed_point_denominator);
  32. }
  33. float CSSPixels::to_float() const
  34. {
  35. return static_cast<float>(m_value) / fixed_point_denominator;
  36. }
  37. double CSSPixels::to_double() const
  38. {
  39. return static_cast<double>(m_value) / fixed_point_denominator;
  40. }
  41. int CSSPixels::to_int() const
  42. {
  43. return m_value / fixed_point_denominator;
  44. }
  45. bool CSSPixels::might_be_saturated() const
  46. {
  47. return raw_value() == NumericLimits<i32>::max() || raw_value() == NumericLimits<i32>::min();
  48. }
  49. bool CSSPixels::operator==(CSSPixels const& other) const
  50. {
  51. return raw_value() == other.raw_value();
  52. }
  53. CSSPixels& CSSPixels::operator++()
  54. {
  55. m_value += fixed_point_denominator;
  56. return *this;
  57. }
  58. CSSPixels& CSSPixels::operator--()
  59. {
  60. m_value -= fixed_point_denominator;
  61. return *this;
  62. }
  63. int CSSPixels::operator<=>(CSSPixels const& other) const
  64. {
  65. return raw_value() > other.raw_value() ? 1 : raw_value() < other.raw_value() ? -1
  66. : 0;
  67. }
  68. CSSPixels CSSPixels::operator+() const
  69. {
  70. CSSPixels result;
  71. result.set_raw_value(+raw_value());
  72. return result;
  73. }
  74. CSSPixels CSSPixels::operator-() const
  75. {
  76. CSSPixels result;
  77. result.set_raw_value(-raw_value());
  78. return result;
  79. }
  80. static inline int saturated_addition(int a, int b)
  81. {
  82. i32 overflow = (b > 0 && a > NumericLimits<i32>::max() - b);
  83. i32 underflow = (b < 0 && a < NumericLimits<i32>::min() - b);
  84. return overflow ? NumericLimits<i32>::max() : (underflow ? NumericLimits<i32>::min() : a + b);
  85. }
  86. CSSPixels CSSPixels::operator+(CSSPixels const& other) const
  87. {
  88. CSSPixels result;
  89. result.set_raw_value(saturated_addition(raw_value(), other.raw_value()));
  90. return result;
  91. }
  92. CSSPixels CSSPixels::operator-(CSSPixels const& other) const
  93. {
  94. CSSPixels result;
  95. result.set_raw_value(raw_value() - other.raw_value());
  96. return result;
  97. }
  98. CSSPixels CSSPixels::operator*(CSSPixels const& other) const
  99. {
  100. CSSPixels result;
  101. result.set_raw_value((raw_value() * other.raw_value()) >> fractional_bits);
  102. return result;
  103. }
  104. CSSPixels CSSPixels::operator/(CSSPixels const& other) const
  105. {
  106. CSSPixels result;
  107. result.set_raw_value(static_cast<long long>(fixed_point_denominator) * raw_value() / other.raw_value());
  108. return result;
  109. }
  110. CSSPixels& CSSPixels::operator+=(CSSPixels const& other)
  111. {
  112. *this = *this + other;
  113. return *this;
  114. }
  115. CSSPixels& CSSPixels::operator-=(CSSPixels const& other)
  116. {
  117. *this = *this - other;
  118. return *this;
  119. }
  120. CSSPixels& CSSPixels::operator*=(CSSPixels const& other)
  121. {
  122. *this = *this * other;
  123. return *this;
  124. }
  125. CSSPixels& CSSPixels::operator/=(CSSPixels const& other)
  126. {
  127. *this = *this / other;
  128. return *this;
  129. }
  130. CSSPixels CSSPixels::abs() const
  131. {
  132. CSSPixels result;
  133. result.set_raw_value(::abs(m_value));
  134. return result;
  135. }
  136. float CSSPixels::epsilon()
  137. {
  138. return 1.0f / fixed_point_denominator;
  139. }
  140. }