Fcitx
rect.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2016-2016 CSSlayer <wengxt@gmail.com>
3  *
4  * SPDX-License-Identifier: LGPL-2.1-or-later
5  *
6  */
7 #ifndef _FCITX_UTILS_RECT_H_
8 #define _FCITX_UTILS_RECT_H_
9 
10 /// \addtogroup FcitxUtils
11 /// \{
12 /// \file
13 /// \brief Provide utility to handle rectangle.
14 
15 #include <algorithm>
16 #include <ostream>
17 #include <utility>
18 #include "fcitxutils_export.h"
19 
20 namespace fcitx {
21 class FCITXUTILS_EXPORT Rect {
22 public:
23  explicit Rect(int _x1 = 0, int _y1 = 0, int _x2 = 0, int _y2 = 0)
24  : x1_(_x1), y1_(_y1), x2_(_x2), y2_(_y2) {}
25 
26  Rect(const Rect &rect) = default;
27  Rect &operator=(const Rect &rect) = default;
28 
29  inline Rect &setPosition(int x, int y) noexcept {
30  x1_ = x;
31  y1_ = y;
32  return *this;
33  }
34 
35  inline Rect &setSize(int width, int height) noexcept {
36  x2_ = width + x1_;
37  y2_ = height + y1_;
38  return *this;
39  }
40 
41  inline Rect &setLeft(int pos) noexcept {
42  x1_ = pos;
43  return *this;
44  }
45  inline Rect &setTop(int pos) noexcept {
46  y1_ = pos;
47  return *this;
48  }
49  inline Rect &setRight(int pos) noexcept {
50  x2_ = pos;
51  return *this;
52  }
53  inline Rect &setBottom(int pos) noexcept {
54  y2_ = pos;
55  return *this;
56  }
57 
58  // FIXME: remove this.
59  inline Rect intersected(const Rect &rect) noexcept {
60  return std::as_const(*this).intersected(rect);
61  }
62 
63  inline Rect intersected(const Rect &rect) const noexcept {
64  Rect tmp;
65  tmp.x1_ = std::max(x1_, rect.x1_);
66  tmp.x2_ = std::min(x2_, rect.x2_);
67  tmp.y1_ = std::max(y1_, rect.y1_);
68  tmp.y2_ = std::min(y2_, rect.y2_);
69  if (tmp.x1_ < tmp.x2_ && tmp.y1_ < tmp.y2_) {
70  return tmp;
71  }
72  return Rect();
73  }
74 
75  // Return a rect with same size, but move by a offset.
76  Rect translated(int offsetX, int offsetY) const {
77  return Rect()
78  .setPosition(x1_ + offsetX, y1_ + offsetY)
79  .setSize(width(), height());
80  }
81 
82  bool contains(int x, int y) const noexcept {
83  return (x1_ <= x && x <= x2_) && (y1_ <= y && y <= y2_);
84  }
85 
86  bool contains(const Rect &other) const noexcept {
87  return contains(other.x1_, other.y1_) && contains(other.x2_, other.y2_);
88  }
89 
90  int distance(int x, int y) const noexcept {
91  int dx = 0;
92  int dy = 0;
93  if (x < x1_) {
94  dx = x1_ - x;
95  } else if (x > x2_) {
96  dx = x - x2_;
97  }
98  if (y < y1_) {
99  dy = y1_ - y;
100  } else if (y > y2_) {
101  dy = y - y2_;
102  }
103  return dx + dy;
104  }
105 
106  inline int left() const noexcept { return x1_; }
107  inline int top() const noexcept { return y1_; }
108  inline int right() const noexcept { return x2_; }
109  inline int bottom() const noexcept { return y2_; }
110 
111  inline int width() const noexcept { return x2_ - x1_; }
112  inline int height() const noexcept { return y2_ - y1_; }
113 
114  inline bool operator==(const Rect &other) const {
115  return x1_ == other.x1_ && x2_ == other.x2_ && y1_ == other.y1_ &&
116  y2_ == other.y2_;
117  }
118 
119  inline bool operator!=(const Rect &other) const {
120  return !operator==(other);
121  }
122 
123  inline bool isEmpty() const { return width() <= 0 || height() <= 0; }
124 
125 private:
126  int x1_, y1_, x2_, y2_;
127 };
128 
129 inline std::ostream &operator<<(std::ostream &os, const Rect &r) {
130  os << "Rect(" << r.left() << "," << r.top() << "+" << r.width() << "x"
131  << r.height() << ")";
132  return os;
133 }
134 
135 }; // namespace fcitx
136 
137 #endif // _FCITX_UTILS_RECT_H_
Definition: action.cpp:12