123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- // Copyright 2022 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef UI_GFX_GEOMETRY_INSETS_OUTSETS_BASE_H_
- #define UI_GFX_GEOMETRY_INSETS_OUTSETS_BASE_H_
- #include <string>
- #include "base/numerics/clamped_math.h"
- #include "base/strings/stringprintf.h"
- #include "ui/gfx/geometry/size.h"
- namespace gfx {
- // The common base template class for Insets and Outsets.
- // Represents the widths of the four borders or margins of an unspecified
- // rectangle. It stores the thickness of the top, left, bottom and right
- // edges, without storing the actual size and position of the rectangle itself.
- template <typename T>
- class InsetsOutsetsBase {
- public:
- constexpr InsetsOutsetsBase() = default;
- constexpr explicit InsetsOutsetsBase(int all)
- : top_(all),
- left_(all),
- bottom_(ClampBottomOrRight(all, all)),
- right_(ClampBottomOrRight(all, all)) {}
- constexpr int top() const { return top_; }
- constexpr int left() const { return left_; }
- constexpr int bottom() const { return bottom_; }
- constexpr int right() const { return right_; }
- // Returns the total width taken up by the insets/outsets, which is the sum
- // of the left and right insets/outsets.
- constexpr int width() const { return left_ + right_; }
- // Returns the total height taken up by the insets/outsets, which is the sum
- // of the top and bottom insets/outsets.
- constexpr int height() const { return top_ + bottom_; }
- // Returns the sum of the left and right insets/outsets as the width,
- // the sum of the top and bottom insets/outsets as the height.
- constexpr Size size() const { return Size(width(), height()); }
- // Returns true if the insets/outsets are empty.
- bool IsEmpty() const { return width() == 0 && height() == 0; }
- // These setters can be used together with the default constructor and the
- // single-parameter constructor to construct Insets instances, for example:
- // // T, L, B, R
- // Insets a = Insets().set_top(2); // 2, 0, 0, 0
- // Insets b = Insets().set_left(2).set_bottom(3); // 0, 2, 3, 0
- // Insets c = Insets().set_left_right(1, 2).set_top_bottom(3, 4);
- // // 3, 1, 4, 2
- // Insets d = Insets(1).set_top(5); // 5, 1, 1, 1
- constexpr T& set_top(int top) {
- top_ = top;
- bottom_ = ClampBottomOrRight(top_, bottom_);
- return *static_cast<T*>(this);
- }
- constexpr T& set_left(int left) {
- left_ = left;
- right_ = ClampBottomOrRight(left_, right_);
- return *static_cast<T*>(this);
- }
- constexpr T& set_bottom(int bottom) {
- bottom_ = ClampBottomOrRight(top_, bottom);
- return *static_cast<T*>(this);
- }
- constexpr T& set_right(int right) {
- right_ = ClampBottomOrRight(left_, right);
- return *static_cast<T*>(this);
- }
- // These are preferred to the above setters when setting a pair of edges
- // because these have less clamping and better performance.
- constexpr T& set_left_right(int left, int right) {
- left_ = left;
- right_ = ClampBottomOrRight(left_, right);
- return *static_cast<T*>(this);
- }
- constexpr T& set_top_bottom(int top, int bottom) {
- top_ = top;
- bottom_ = ClampBottomOrRight(top_, bottom);
- return *static_cast<T*>(this);
- }
- // In addition to the above, we can also use the following methods to
- // construct Insets/Outsets.
- // TLBR() is for Chomium UI code. We should not use it in blink code because
- // the order of parameters is different from the normal orders used in blink.
- // Blink code can use the above setters and VH().
- static constexpr T TLBR(int top, int left, int bottom, int right) {
- return T().set_top_bottom(top, bottom).set_left_right(left, right);
- }
- static constexpr T VH(int vertical, int horizontal) {
- return TLBR(vertical, horizontal, vertical, horizontal);
- }
- // Sets each side to the maximum of the side and the corresponding side of
- // |other|.
- void SetToMax(const T& other) {
- top_ = std::max(top_, other.top_);
- left_ = std::max(left_, other.left_);
- bottom_ = std::max(bottom_, other.bottom_);
- right_ = std::max(right_, other.right_);
- }
- bool operator==(const InsetsOutsetsBase<T>& other) const {
- return top_ == other.top_ && left_ == other.left_ &&
- bottom_ == other.bottom_ && right_ == other.right_;
- }
- bool operator!=(const InsetsOutsetsBase<T>& other) const {
- return !(*this == other);
- }
- void operator+=(const T& other) {
- top_ = base::ClampAdd(top_, other.top_);
- left_ = base::ClampAdd(left_, other.left_);
- bottom_ = ClampBottomOrRight(top_, base::ClampAdd(bottom_, other.bottom_));
- right_ = ClampBottomOrRight(left_, base::ClampAdd(right_, other.right_));
- }
- void operator-=(const T& other) {
- top_ = base::ClampSub(top_, other.top_);
- left_ = base::ClampSub(left_, other.left_);
- bottom_ = ClampBottomOrRight(top_, base::ClampSub(bottom_, other.bottom_));
- right_ = ClampBottomOrRight(left_, base::ClampSub(right_, other.right_));
- }
- T operator-() const {
- return T()
- .set_left_right(-base::MakeClampedNum(left_),
- -base::MakeClampedNum(right_))
- .set_top_bottom(-base::MakeClampedNum(top_),
- -base::MakeClampedNum(bottom_));
- }
- // Returns a string representation of the insets/outsets.
- std::string ToString() const {
- return base::StringPrintf("x:%d,%d y:%d,%d", left_, right_, top_, bottom_);
- }
- private:
- // Clamp the bottom/right to avoid integer over/underflow in width() and
- // height(). This returns the clamped bottom/right given a |top_or_left| and
- // a |bottom_or_right|.
- static constexpr int ClampBottomOrRight(int top_or_left,
- int bottom_or_right) {
- return base::ClampAdd(top_or_left, bottom_or_right) - top_or_left;
- }
- int top_ = 0;
- int left_ = 0;
- int bottom_ = 0;
- int right_ = 0;
- };
- } // namespace gfx
- #endif // UI_GFX_GEOMETRY_INSETS_OUTSETS_BASE_H_
|