diff options
author | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-11 09:07:01 +0000 |
---|---|---|
committer | oshima@chromium.org <oshima@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-11 09:07:01 +0000 |
commit | e5c45f6c5f6778f1da0053ccbb8d95a15bdbcc14 (patch) | |
tree | d319bff466a413f5e090a542e058ce7ef7ed2b85 /ui/gfx/rect_base_impl.h | |
parent | 394633964593be10c6bb220c73083e1b8308bf23 (diff) | |
download | chromium_src-e5c45f6c5f6778f1da0053ccbb8d95a15bdbcc14.zip chromium_src-e5c45f6c5f6778f1da0053ccbb8d95a15bdbcc14.tar.gz chromium_src-e5c45f6c5f6778f1da0053ccbb8d95a15bdbcc14.tar.bz2 |
Use template for Point/Size/Rect and remove duplicates
BUG=114664
TEST=none
Review URL: https://chromiumcodereview.appspot.com/10014027
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131737 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/gfx/rect_base_impl.h')
-rw-r--r-- | ui/gfx/rect_base_impl.h | 318 |
1 files changed, 318 insertions, 0 deletions
diff --git a/ui/gfx/rect_base_impl.h b/ui/gfx/rect_base_impl.h new file mode 100644 index 0000000..84caa76 --- /dev/null +++ b/ui/gfx/rect_base_impl.h @@ -0,0 +1,318 @@ +// Copyright (c) 2012 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. + +#include "ui/gfx/rect_base.h" + +#include "base/logging.h" +#include "base/stringprintf.h" + +// This file provides the implementation for RectBaese template and +// used to instantiate the base class for Rect and RectF classes. +#if !defined(UI_IMPLEMENTATION) +#error "This file is intended for UI implementation only" +#endif + +namespace { + +template<typename Type> +void AdjustAlongAxis(Type dst_origin, Type dst_size, Type* origin, Type* size) { + *size = std::min(dst_size, *size); + if (*origin < dst_origin) + *origin = dst_origin; + else + *origin = std::min(dst_origin + dst_size, *origin + *size) - *size; +} + +} // namespace + +namespace gfx { + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::RectBase( + const PointClass& origin, const SizeClass& size) + : origin_(origin), size_(size) { +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::RectBase( + const SizeClass& size) + : size_(size) { +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::RectBase( + const PointClass& origin) + : origin_(origin) { +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::~RectBase() {} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +void RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::SetRect( + Type x, Type y, Type width, Type height) { + origin_.SetPoint(x, y); + set_width(width); + set_height(height); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +void RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::Inset( + const InsetsClass& insets) { + Inset(insets.left(), insets.top(), insets.right(), insets.bottom()); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +void RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::Inset( + Type left, Type top, Type right, Type bottom) { + Offset(left, top); + set_width(std::max(width() - left - right, static_cast<Type>(0))); + set_height(std::max(height() - top - bottom, static_cast<Type>(0))); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +void RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::Offset( + Type horizontal, Type vertical) { + origin_.Offset(horizontal, vertical); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +bool RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::operator==( + const Class& other) const { + return origin_ == other.origin_ && size_ == other.size_; +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +bool RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::operator<( + const Class& other) const { + if (origin_ == other.origin_) { + if (width() == other.width()) { + return height() < other.height(); + } else { + return width() < other.width(); + } + } else { + return origin_ < other.origin_; + } +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +bool RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::Contains( + Type point_x, Type point_y) const { + return (point_x >= x()) && (point_x < right()) && + (point_y >= y()) && (point_y < bottom()); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +bool RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::Contains( + const Class& rect) const { + return (rect.x() >= x() && rect.right() <= right() && + rect.y() >= y() && rect.bottom() <= bottom()); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +bool RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::Intersects( + const Class& rect) const { + return !(rect.x() >= right() || rect.right() <= x() || + rect.y() >= bottom() || rect.bottom() <= y()); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +Class RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::Intersect( + const Class& rect) const { + Type rx = std::max(x(), rect.x()); + Type ry = std::max(y(), rect.y()); + Type rr = std::min(right(), rect.right()); + Type rb = std::min(bottom(), rect.bottom()); + + if (rx >= rr || ry >= rb) + rx = ry = rr = rb = 0; // non-intersecting + + return Class(rx, ry, rr - rx, rb - ry); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +Class RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::Union( + const Class& rect) const { + // special case empty rects... + if (IsEmpty()) + return rect; + if (rect.IsEmpty()) + return *static_cast<const Class*>(this); + + Type rx = std::min(x(), rect.x()); + Type ry = std::min(y(), rect.y()); + Type rr = std::max(right(), rect.right()); + Type rb = std::max(bottom(), rect.bottom()); + + return Class(rx, ry, rr - rx, rb - ry); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +Class RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::Subtract( + const Class& rect) const { + // boundary cases: + if (!Intersects(rect)) + return *static_cast<const Class*>(this); + if (rect.Contains(*static_cast<const Class*>(this))) + return Class(); + + Type rx = x(); + Type ry = y(); + Type rr = right(); + Type rb = bottom(); + + if (rect.y() <= y() && rect.bottom() >= bottom()) { + // complete intersection in the y-direction + if (rect.x() <= x()) { + rx = rect.right(); + } else { + rr = rect.x(); + } + } else if (rect.x() <= x() && rect.right() >= right()) { + // complete intersection in the x-direction + if (rect.y() <= y()) { + ry = rect.bottom(); + } else { + rb = rect.y(); + } + } + return Class(rx, ry, rr - rx, rb - ry); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +Class RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::AdjustToFit( + const Class& rect) const { + Type new_x = x(); + Type new_y = y(); + Type new_width = width(); + Type new_height = height(); + AdjustAlongAxis(rect.x(), rect.width(), &new_x, &new_width); + AdjustAlongAxis(rect.y(), rect.height(), &new_y, &new_height); + return Class(new_x, new_y, new_width, new_height); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +PointClass RectBase<Class, PointClass, SizeClass, InsetsClass, Type>:: + CenterPoint() const { + return PointClass(x() + (width() - 1) / 2, y() + (height() - 1) / 2); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +Class RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::Center( + const SizeClass& size) const { + Type new_width = std::min(width(), size.width()); + Type new_height = std::min(height(), size.height()); + Type new_x = x() + (width() - new_width) / 2; + Type new_y = y() + (height() - new_height) / 2; + return Class(new_x, new_y, new_width, new_height); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +void RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::SplitVertically( + Class* left_half, Class* right_half) const { + DCHECK(left_half); + DCHECK(right_half); + + left_half->SetRect(this->x(), this->y(), this->width() / 2, this->height()); + right_half->SetRect(left_half->right(), + this->y(), + this->width() - left_half->width(), + this->height()); +} + +template<typename Class, + typename PointClass, + typename SizeClass, + typename InsetsClass, + typename Type> +bool RectBase<Class, PointClass, SizeClass, InsetsClass, Type>::SharesEdgeWith( + const Class& rect) const { + return (y() == rect.y() && height() == rect.height() && + (x() == rect.right() || right() == rect.x())) || + (x() == rect.x() && width() == rect.width() && + (y() == rect.bottom() || bottom() == rect.y())); +} + +} // namespace gfx |