15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A template for a simple rectangle class.  The containment semantics
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are array-like; that is, the coordinate (x, y) is considered to be
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contained by the rectangle, but the coordinate (x + width, y) is not.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The class will happily let you create malformed rectangles (that is,
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rectangles with negative width and/or height), but there will be assertions
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the operations (such as Contains()) to complain in this case.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifndef UI_GFX_GEOMETRY_RECT_BASE_H_
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#define UI_GFX_GEOMETRY_RECT_BASE_H_
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template<typename Class,
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         typename PointClass,
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         typename SizeClass,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         typename InsetsClass,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         typename VectorClass,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         typename Type>
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class GFX_EXPORT RectBase {
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Type x() const { return origin_.x(); }
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_x(Type x) { origin_.set_x(x); }
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Type y() const { return origin_.y(); }
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_y(Type y) { origin_.set_y(y); }
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Type width() const { return size_.width(); }
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_width(Type width) { size_.set_width(width); }
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Type height() const { return size_.height(); }
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_height(Type height) { size_.set_height(height); }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const PointClass& origin() const { return origin_; }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_origin(const PointClass& origin) { origin_ = origin; }
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const SizeClass& size() const { return size_; }
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_size(const SizeClass& size) { size_ = size; }
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Type right() const { return x() + width(); }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Type bottom() const { return y() + height(); }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PointClass top_right() const { return PointClass(right(), y()); }
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PointClass bottom_left() const { return PointClass(x(), bottom()); }
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PointClass bottom_right() const { return PointClass(right(), bottom()); }
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VectorClass OffsetFromOrigin() const {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return VectorClass(x(), y());
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetRect(Type x, Type y, Type width, Type height);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shrink the rectangle by a horizontal and vertical distance on all sides.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Inset(Type horizontal, Type vertical) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Inset(horizontal, vertical, horizontal, vertical);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shrink the rectangle by the given insets.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Inset(const InsetsClass& insets);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Shrink the rectangle by the specified amount on each side.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Inset(Type left, Type top, Type right, Type bottom);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Move the rectangle by a horizontal and vertical distance.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Offset(Type horizontal, Type vertical);
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Offset(const VectorClass& distance) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Offset(distance.x(), distance.y());
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void operator+=(const VectorClass& offset);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void operator-=(const VectorClass& offset);
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InsetsClass InsetsFrom(const Class& inner) const {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return InsetsClass(inner.y() - y(),
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       inner.x() - x(),
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       bottom() - inner.bottom(),
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       right() - inner.right());
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the area of the rectangle is zero.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool IsEmpty() const { return size_.IsEmpty(); }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A rect is less than another rect if its origin is less than
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the other rect's origin. If the origins are equal, then the
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // shortest rect is less than the other. If the origin and the
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // height are equal, then the narrowest rect is less than.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This comparison is required to use Rects in sets, or sorted
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // vectors.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool operator<(const Class& other) const;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the point identified by point_x and point_y falls inside
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this rectangle.  The point (x, y) is inside the rectangle, but the
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // point (x + width, y + height) is not.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Contains(Type point_x, Type point_y) const;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the specified point is contained by this rectangle.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Contains(const PointClass& point) const {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Contains(point.x(), point.y());
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if this rectangle contains the specified rectangle.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Contains(const Class& rect) const;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if this rectangle intersects the specified rectangle.
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // An empty rectangle doesn't intersect any rectangle.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Intersects(const Class& rect) const;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Computes the intersection of this rectangle with the given rectangle.
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Intersect(const Class& rect);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Computes the union of this rectangle with the given rectangle.  The union
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is the smallest rectangle containing both rectangles.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Union(const Class& rect);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Computes the rectangle resulting from subtracting |rect| from |*this|,
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // i.e. the bounding rect of |Region(*this) - Region(rect)|.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Subtract(const Class& rect);
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fits as much of the receiving rectangle into the supplied rectangle as
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // possible, becoming the result. For example, if the receiver had
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a x-location of 2 and a width of 4, and the supplied rectangle had
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an x-location of 0 with a width of 5, the returned rectangle would have
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // an x-location of 1 with a width of 4.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AdjustToFit(const Class& rect);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the center of this rectangle.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PointClass CenterPoint() const;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Becomes a rectangle that has the same center point but with a size capped
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // at given |size|.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ClampToCenteredSize(const SizeClass& size);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Splits |this| in two halves, |left_half| and |right_half|.
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SplitVertically(Class* left_half, Class* right_half) const;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if this rectangle shares an entire edge (i.e., same width or
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // same height) with the given rectangle, and the rectangles do not overlap.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SharesEdgeWith(const Class& rect) const;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Returns the manhattan distance from the rect to the point. If the point is
14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // inside the rect, returns 0.
14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Type ManhattanDistanceToPoint(const PointClass& point) const;
14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns the manhattan distance between the contents of this rect and the
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // contents of the given rect. That is, if the intersection of the two rects
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // is non-empty then the function returns 0. If the rects share a side, it
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // returns the smallest non-zero value appropriate for Type.
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  Type ManhattanInternalDistance(const Class& rect) const;
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RectBase(const PointClass& origin, const SizeClass& size)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : origin_(origin), size_(size) {}
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit RectBase(const SizeClass& size)
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : size_(size) {}
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit RectBase(const PointClass& origin)
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : origin_(origin) {}
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Destructor is intentionally made non virtual and protected.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not make this public.
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~RectBase() {}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PointClass origin_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SizeClass size_;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // UI_GFX_GEOMETRY_RECT_BASE_H_
175