Home | History | Annotate | Download | only in gfx
      1 // Copyright (c) 2012 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 // Defines a simple integer rectangle class.  The containment semantics
      6 // are array-like; that is, the coordinate (x, y) is considered to be
      7 // contained by the rectangle, but the coordinate (x + width, y) is not.
      8 // The class will happily let you create malformed rectangles (that is,
      9 // rectangles with negative width and/or height), but there will be assertions
     10 // in the operations (such as Contains()) to complain in this case.
     11 
     12 #ifndef UI_GFX_RECT_H_
     13 #define UI_GFX_RECT_H_
     14 
     15 #include <cmath>
     16 #include <string>
     17 
     18 #include "ui/gfx/point.h"
     19 #include "ui/gfx/rect_base.h"
     20 #include "ui/gfx/rect_f.h"
     21 #include "ui/gfx/size.h"
     22 #include "ui/gfx/vector2d.h"
     23 
     24 #if defined(OS_WIN)
     25 typedef struct tagRECT RECT;
     26 #elif defined(TOOLKIT_GTK)
     27 typedef struct _GdkRectangle GdkRectangle;
     28 #elif defined(OS_IOS)
     29 #include <CoreGraphics/CoreGraphics.h>
     30 #elif defined(OS_MACOSX)
     31 #include <ApplicationServices/ApplicationServices.h>
     32 #endif
     33 
     34 namespace gfx {
     35 
     36 class Insets;
     37 
     38 class UI_EXPORT Rect
     39     : public RectBase<Rect, Point, Size, Insets, Vector2d, int> {
     40  public:
     41   Rect() : RectBase<Rect, Point, Size, Insets, Vector2d, int>(Point()) {}
     42 
     43   Rect(int width, int height)
     44       : RectBase<Rect, Point, Size, Insets, Vector2d, int>
     45             (Size(width, height)) {}
     46 
     47   Rect(int x, int y, int width, int height)
     48       : RectBase<Rect, Point, Size, Insets, Vector2d, int>
     49             (Point(x, y), Size(width, height)) {}
     50 
     51 #if defined(OS_WIN)
     52   explicit Rect(const RECT& r);
     53 #elif defined(OS_MACOSX)
     54   explicit Rect(const CGRect& r);
     55 #elif defined(TOOLKIT_GTK)
     56   explicit Rect(const GdkRectangle& r);
     57 #endif
     58 
     59   explicit Rect(const gfx::Size& size)
     60       : RectBase<Rect, Point, Size, Insets, Vector2d, int>(size) {}
     61 
     62   Rect(const gfx::Point& origin, const gfx::Size& size)
     63       : RectBase<Rect, Point, Size, Insets, Vector2d, int>(origin, size) {}
     64 
     65   ~Rect() {}
     66 
     67 #if defined(OS_WIN)
     68   // Construct an equivalent Win32 RECT object.
     69   RECT ToRECT() const;
     70 #elif defined(TOOLKIT_GTK)
     71   GdkRectangle ToGdkRectangle() const;
     72 #elif defined(OS_MACOSX)
     73   // Construct an equivalent CoreGraphics object.
     74   CGRect ToCGRect() const;
     75 #endif
     76 
     77   operator RectF() const {
     78     return RectF(origin().x(), origin().y(), size().width(), size().height());
     79   }
     80 
     81   std::string ToString() const;
     82 };
     83 
     84 inline bool operator==(const Rect& lhs, const Rect& rhs) {
     85   return lhs.origin() == rhs.origin() && lhs.size() == rhs.size();
     86 }
     87 
     88 inline bool operator!=(const Rect& lhs, const Rect& rhs) {
     89   return !(lhs == rhs);
     90 }
     91 
     92 UI_EXPORT Rect operator+(const Rect& lhs, const Vector2d& rhs);
     93 UI_EXPORT Rect operator-(const Rect& lhs, const Vector2d& rhs);
     94 
     95 inline Rect operator+(const Vector2d& lhs, const Rect& rhs) {
     96   return rhs + lhs;
     97 }
     98 
     99 UI_EXPORT Rect IntersectRects(const Rect& a, const Rect& b);
    100 UI_EXPORT Rect UnionRects(const Rect& a, const Rect& b);
    101 UI_EXPORT Rect SubtractRects(const Rect& a, const Rect& b);
    102 
    103 // Constructs a rectangle with |p1| and |p2| as opposite corners.
    104 //
    105 // This could also be thought of as "the smallest rect that contains both
    106 // points", except that we consider points on the right/bottom edges of the
    107 // rect to be outside the rect.  So technically one or both points will not be
    108 // contained within the rect, because they will appear on one of these edges.
    109 UI_EXPORT Rect BoundingRect(const Point& p1, const Point& p2);
    110 
    111 inline Rect ScaleToEnclosingRect(const Rect& rect,
    112                                  float x_scale,
    113                                  float y_scale) {
    114   int x = std::floor(rect.x() * x_scale);
    115   int y = std::floor(rect.y() * y_scale);
    116   int r = rect.width() == 0 ? x : std::ceil(rect.right() * x_scale);
    117   int b = rect.height() == 0 ? y : std::ceil(rect.bottom() * y_scale);
    118   return Rect(x, y, r - x, b - y);
    119 }
    120 
    121 inline Rect ScaleToEnclosingRect(const Rect& rect, float scale) {
    122   return ScaleToEnclosingRect(rect, scale, scale);
    123 }
    124 
    125 inline Rect ScaleToEnclosedRect(const Rect& rect,
    126                                 float x_scale,
    127                                 float y_scale) {
    128   int x = std::ceil(rect.x() * x_scale);
    129   int y = std::ceil(rect.y() * y_scale);
    130   int r = rect.width() == 0 ? x : std::floor(rect.right() * x_scale);
    131   int b = rect.height() == 0 ? y : std::floor(rect.bottom() * y_scale);
    132   return Rect(x, y, r - x, b - y);
    133 }
    134 
    135 inline Rect ScaleToEnclosedRect(const Rect& rect, float scale) {
    136   return ScaleToEnclosedRect(rect, scale, scale);
    137 }
    138 
    139 #if !defined(COMPILER_MSVC)
    140 extern template class RectBase<Rect, Point, Size, Insets, Vector2d, int>;
    141 #endif
    142 
    143 }  // namespace gfx
    144 
    145 #endif  // UI_GFX_RECT_H_
    146