1 // Copyright 2015 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 
5 #ifndef UI_GFX_RANGE_RANGE_F_H_
6 #define UI_GFX_RANGE_RANGE_F_H_
7 
8 #include <limits>
9 #include <ostream>
10 #include <string>
11 
12 #include "ui/gfx/range/gfx_range_export.h"
13 #include "ui/gfx/range/range.h"
14 
15 namespace gfx {
16 
17 // A float version of Range. RangeF is made of a start and end position; when
18 // they are the same, the range is empty. Note that |start_| can be greater
19 // than |end_| to respect the directionality of the range.
20 class GFX_RANGE_EXPORT RangeF {
21  public:
22   // Creates an empty range {0,0}.
RangeF()23   constexpr RangeF() : RangeF(0.f) {}
24 
25   // Initializes the range with a start and end.
RangeF(float start,float end)26   constexpr RangeF(float start, float end) : start_(start), end_(end) {}
27 
28   // Initializes the range with the same start and end positions.
RangeF(float position)29   constexpr explicit RangeF(float position) : RangeF(position, position) {}
30 
31   // Returns a range that is invalid, which is {float_max,float_max}.
InvalidRange()32   static constexpr RangeF InvalidRange() {
33     return RangeF(std::numeric_limits<float>::max());
34   }
35 
36   // Checks if the range is valid through comparison to InvalidRange().
IsValid()37   constexpr bool IsValid() const { return *this != InvalidRange(); }
38 
39   // Getters and setters.
start()40   constexpr float start() const { return start_; }
set_start(float start)41   void set_start(float start) { start_ = start; }
42 
end()43   constexpr float end() const { return end_; }
set_end(float end)44   void set_end(float end) { end_ = end; }
45 
46   // Returns the absolute value of the length.
length()47   constexpr float length() const { return GetMax() - GetMin(); }
48 
is_reversed()49   constexpr bool is_reversed() const { return start() > end(); }
is_empty()50   constexpr bool is_empty() const { return start() == end(); }
51 
52   // Returns the minimum and maximum values.
GetMin()53   constexpr float GetMin() const { return start() < end() ? start() : end(); }
GetMax()54   constexpr float GetMax() const { return start() > end() ? start() : end(); }
55 
56   constexpr bool operator==(const RangeF& other) const {
57     return start() == other.start() && end() == other.end();
58   }
59   constexpr bool operator!=(const RangeF& other) const {
60     return !(*this == other);
61   }
EqualsIgnoringDirection(const RangeF & other)62   constexpr bool EqualsIgnoringDirection(const RangeF& other) const {
63     return GetMin() == other.GetMin() && GetMax() == other.GetMax();
64   }
65 
66   // Returns true if this range intersects the specified |range|.
Intersects(const RangeF & range)67   constexpr bool Intersects(const RangeF& range) const {
68     return Intersect(range).IsValid();
69   }
70 
71   // Returns true if this range is contained by the specified |range| or it is
72   // an empty range and ending the range |range|. (copied from gfx::Range)
IsBoundedBy(const RangeF & range)73   constexpr bool IsBoundedBy(const RangeF& range) const {
74     return IsValid() && range.IsValid() && GetMin() >= range.GetMin() &&
75            GetMax() <= range.GetMax();
76   }
77 
78   // Returns true if this range contains the specified |range|.
Contains(const RangeF & range)79   constexpr bool Contains(const RangeF& range) const {
80     return range.IsBoundedBy(*this) &&
81            // A non-empty range doesn't contain the range [max, max).
82            (range.GetMax() != GetMax() || range.is_empty() == is_empty());
83   }
84 
85   // Computes the intersection of this range with the given |range|.
86   // If they don't intersect, it returns an InvalidRange().
87   // The returned range is always empty or forward (never reversed).
Intersect(const RangeF & range)88   constexpr RangeF Intersect(const RangeF& range) const {
89     const float min = std::max(GetMin(), range.GetMin());
90     const float max = std::min(GetMax(), range.GetMax());
91 
92     return (min < max || Contains(range) || range.Contains(*this))
93                ? RangeF(min, max)
94                : InvalidRange();
95   }
96 
97   RangeF Intersect(const Range& range) const;
98 
99   // Floor/Ceil/Round the start and end values of the given RangeF.
100   Range Floor() const;
101   Range Ceil() const;
102   Range Round() const;
103 
104   std::string ToString() const;
105 
106  private:
107   float start_;
108   float end_;
109 };
110 
111 GFX_RANGE_EXPORT std::ostream& operator<<(std::ostream& os,
112                                           const RangeF& range);
113 
114 }  // namespace gfx
115 
116 #endif  // UI_GFX_RANGE_RANGE_F_H_
117