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)// Defines a simple integer 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)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef UI_GFX_RECT_H_
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UI_GFX_RECT_H_
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <cmath>
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect_base.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect_f.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/vector2d.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct tagRECT RECT;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(TOOLKIT_GTK)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _GdkRectangle GdkRectangle;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_IOS)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <CoreGraphics/CoreGraphics.h>
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ApplicationServices/ApplicationServices.h>
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gfx {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Insets;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UI_EXPORT Rect
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public RectBase<Rect, Point, Size, Insets, Vector2d, int> {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Rect() : RectBase<Rect, Point, Size, Insets, Vector2d, int>(Point()) {}
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Rect(int width, int height)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : RectBase<Rect, Point, Size, Insets, Vector2d, int>
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            (Size(width, height)) {}
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Rect(int x, int y, int width, int height)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : RectBase<Rect, Point, Size, Insets, Vector2d, int>
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            (Point(x, y), Size(width, height)) {}
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit Rect(const RECT& r);
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit Rect(const CGRect& r);
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(TOOLKIT_GTK)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit Rect(const GdkRectangle& r);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit Rect(const gfx::Size& size)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : RectBase<Rect, Point, Size, Insets, Vector2d, int>(size) {}
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Rect(const gfx::Point& origin, const gfx::Size& size)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      : RectBase<Rect, Point, Size, Insets, Vector2d, int>(origin, size) {}
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ~Rect() {}
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct an equivalent Win32 RECT object.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RECT ToRECT() const;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(TOOLKIT_GTK)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GdkRectangle ToGdkRectangle() const;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Construct an equivalent CoreGraphics object.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CGRect ToCGRect() const;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  operator RectF() const {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return RectF(origin().x(), origin().y(), size().width(), size().height());
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string ToString() const;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool operator==(const Rect& lhs, const Rect& rhs) {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return lhs.origin() == rhs.origin() && lhs.size() == rhs.size();
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline bool operator!=(const Rect& lhs, const Rect& rhs) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !(lhs == rhs);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UI_EXPORT Rect operator+(const Rect& lhs, const Vector2d& rhs);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UI_EXPORT Rect operator-(const Rect& lhs, const Vector2d& rhs);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline Rect operator+(const Vector2d& lhs, const Rect& rhs) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return rhs + lhs;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UI_EXPORT Rect IntersectRects(const Rect& a, const Rect& b);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UI_EXPORT Rect UnionRects(const Rect& a, const Rect& b);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UI_EXPORT Rect SubtractRects(const Rect& a, const Rect& b);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Constructs a rectangle with |p1| and |p2| as opposite corners.
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This could also be thought of as "the smallest rect that contains both
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// points", except that we consider points on the right/bottom edges of the
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rect to be outside the rect.  So technically one or both points will not be
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contained within the rect, because they will appear on one of these edges.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UI_EXPORT Rect BoundingRect(const Point& p1, const Point& p2);
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)inline Rect ScaleToEnclosingRect(const Rect& rect,
11290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 float x_scale,
11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                 float y_scale) {
11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int x = std::floor(rect.x() * x_scale);
11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int y = std::floor(rect.y() * y_scale);
11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int r = rect.width() == 0 ? x : std::ceil(rect.right() * x_scale);
11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int b = rect.height() == 0 ? y : std::ceil(rect.bottom() * y_scale);
11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return Rect(x, y, r - x, b - y);
11990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)inline Rect ScaleToEnclosingRect(const Rect& rect, float scale) {
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return ScaleToEnclosingRect(rect, scale, scale);
12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
12490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
12590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)inline Rect ScaleToEnclosedRect(const Rect& rect,
12690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                float x_scale,
12790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)                                float y_scale) {
12890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int x = std::ceil(rect.x() * x_scale);
12990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int y = std::ceil(rect.y() * y_scale);
13090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int r = rect.width() == 0 ? x : std::floor(rect.right() * x_scale);
13190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int b = rect.height() == 0 ? y : std::floor(rect.bottom() * y_scale);
13290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return Rect(x, y, r - x, b - y);
13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)inline Rect ScaleToEnclosedRect(const Rect& rect, float scale) {
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return ScaleToEnclosedRect(rect, scale, scale);
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(COMPILER_MSVC)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern template class RectBase<Rect, Point, Size, Insets, Vector2d, int>;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace gfx
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // UI_GFX_RECT_H_
146