size_f.h 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef UI_GFX_GEOMETRY_SIZE_F_H_
  5. #define UI_GFX_GEOMETRY_SIZE_F_H_
  6. #include <iosfwd>
  7. #include <string>
  8. #include "base/gtest_prod_util.h"
  9. #include "build/build_config.h"
  10. #include "ui/gfx/geometry/geometry_export.h"
  11. #include "ui/gfx/geometry/size.h"
  12. #if BUILDFLAG(IS_APPLE)
  13. struct CGSize;
  14. #endif
  15. namespace gfx {
  16. FORWARD_DECLARE_TEST(SizeTest, TrivialDimensionTests);
  17. FORWARD_DECLARE_TEST(SizeTest, ClampsToZero);
  18. FORWARD_DECLARE_TEST(SizeTest, ConsistentClamping);
  19. // A floating version of gfx::Size.
  20. class GEOMETRY_EXPORT SizeF {
  21. public:
  22. constexpr SizeF() : width_(0.f), height_(0.f) {}
  23. constexpr SizeF(float width, float height)
  24. : width_(clamp(width)), height_(clamp(height)) {}
  25. constexpr explicit SizeF(const Size& size)
  26. : SizeF(static_cast<float>(size.width()),
  27. static_cast<float>(size.height())) {}
  28. #if BUILDFLAG(IS_APPLE)
  29. explicit SizeF(const CGSize&);
  30. CGSize ToCGSize() const;
  31. #endif
  32. constexpr float width() const { return width_; }
  33. constexpr float height() const { return height_; }
  34. void set_width(float width) { width_ = clamp(width); }
  35. void set_height(float height) { height_ = clamp(height); }
  36. void operator+=(const SizeF& size) {
  37. SetSize(width_ + size.width_, height_ + size.height_);
  38. }
  39. void operator-=(const SizeF& size) {
  40. SetSize(width_ - size.width_, height_ - size.height_);
  41. }
  42. float GetArea() const;
  43. float AspectRatio() const { return width_ / height_; }
  44. void SetSize(float width, float height) {
  45. set_width(width);
  46. set_height(height);
  47. }
  48. void Enlarge(float grow_width, float grow_height);
  49. void SetToMin(const SizeF& other);
  50. void SetToMax(const SizeF& other);
  51. // Expands width/height to the next representable value.
  52. void SetToNextWidth() { width_ = next(width_); }
  53. void SetToNextHeight() { height_ = next(height_); }
  54. constexpr bool IsEmpty() const { return !width() || !height(); }
  55. constexpr bool IsZero() const { return !width() && !height(); }
  56. void Scale(float scale) {
  57. Scale(scale, scale);
  58. }
  59. void Scale(float x_scale, float y_scale) {
  60. SetSize(width() * x_scale, height() * y_scale);
  61. }
  62. void Transpose() {
  63. using std::swap;
  64. swap(width_, height_);
  65. }
  66. std::string ToString() const;
  67. private:
  68. FRIEND_TEST_ALL_PREFIXES(SizeFTest, IsEmpty);
  69. FRIEND_TEST_ALL_PREFIXES(SizeFTest, ClampsToZero);
  70. FRIEND_TEST_ALL_PREFIXES(SizeFTest, ConsistentClamping);
  71. static constexpr float kTrivial = 8.f * std::numeric_limits<float>::epsilon();
  72. static constexpr float clamp(float f) { return f > kTrivial ? f : 0.f; }
  73. static float next(float f) {
  74. return std::nextafter(std::max(kTrivial, f),
  75. std::numeric_limits<float>::max());
  76. }
  77. float width_;
  78. float height_;
  79. };
  80. constexpr bool operator==(const SizeF& lhs, const SizeF& rhs) {
  81. return lhs.width() == rhs.width() && lhs.height() == rhs.height();
  82. }
  83. constexpr bool operator!=(const SizeF& lhs, const SizeF& rhs) {
  84. return !(lhs == rhs);
  85. }
  86. inline SizeF operator+(const SizeF& lhs, const SizeF& rhs) {
  87. return SizeF(lhs.width() + rhs.width(), lhs.height() + rhs.height());
  88. }
  89. inline SizeF operator-(const SizeF& lhs, const SizeF& rhs) {
  90. return SizeF(lhs.width() - rhs.width(), lhs.height() - rhs.height());
  91. }
  92. GEOMETRY_EXPORT SizeF ScaleSize(const SizeF& p, float x_scale, float y_scale);
  93. inline SizeF ScaleSize(const SizeF& p, float scale) {
  94. return ScaleSize(p, scale, scale);
  95. }
  96. inline SizeF TransposeSize(const SizeF& s) {
  97. return SizeF(s.height(), s.width());
  98. }
  99. // This is declared here for use in gtest-based unit tests but is defined in
  100. // the //ui/gfx:test_support target. Depend on that to use this in your unit
  101. // test. This should not be used in production code - call ToString() instead.
  102. void PrintTo(const SizeF& size, ::std::ostream* os);
  103. } // namespace gfx
  104. #endif // UI_GFX_GEOMETRY_SIZE_F_H_