| Index: cc/base/math_util.h
|
| diff --git a/cc/base/math_util.h b/cc/base/math_util.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..64a819e85a8cc72c6a00844cefa7987d3815146d
|
| --- /dev/null
|
| +++ b/cc/base/math_util.h
|
| @@ -0,0 +1,246 @@
|
| +// Copyright 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.
|
| +
|
| +#ifndef CC_BASE_MATH_UTIL_H_
|
| +#define CC_BASE_MATH_UTIL_H_
|
| +
|
| +#include <algorithm>
|
| +#include <cmath>
|
| +#include <vector>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "ui/gfx/geometry/box_f.h"
|
| +#include "ui/gfx/geometry/point3_f.h"
|
| +#include "ui/gfx/geometry/point_f.h"
|
| +#include "ui/gfx/geometry/scroll_offset.h"
|
| +#include "ui/gfx/geometry/size.h"
|
| +#include "ui/gfx/transform.h"
|
| +
|
| +namespace base {
|
| +class Value;
|
| +namespace trace_event {
|
| +class TracedValue;
|
| +}
|
| +} // namespace base
|
| +
|
| +namespace gfx {
|
| +class QuadF;
|
| +class Rect;
|
| +class RectF;
|
| +class Transform;
|
| +class Vector2dF;
|
| +class Vector2d;
|
| +}
|
| +
|
| +namespace cc {
|
| +
|
| +struct HomogeneousCoordinate {
|
| + HomogeneousCoordinate(SkMScalar x, SkMScalar y, SkMScalar z, SkMScalar w) {
|
| + vec[0] = x;
|
| + vec[1] = y;
|
| + vec[2] = z;
|
| + vec[3] = w;
|
| + }
|
| +
|
| + bool ShouldBeClipped() const { return w() <= 0.0; }
|
| +
|
| + gfx::PointF CartesianPoint2d() const {
|
| + if (w() == SK_MScalar1)
|
| + return gfx::PointF(x(), y());
|
| +
|
| + // For now, because this code is used privately only by MathUtil, it should
|
| + // never be called when w == 0, and we do not yet need to handle that case.
|
| + DCHECK(w());
|
| + SkMScalar inv_w = SK_MScalar1 / w();
|
| + return gfx::PointF(x() * inv_w, y() * inv_w);
|
| + }
|
| +
|
| + gfx::Point3F CartesianPoint3d() const {
|
| + if (w() == SK_MScalar1)
|
| + return gfx::Point3F(x(), y(), z());
|
| +
|
| + // For now, because this code is used privately only by MathUtil, it should
|
| + // never be called when w == 0, and we do not yet need to handle that case.
|
| + DCHECK(w());
|
| + SkMScalar inv_w = SK_MScalar1 / w();
|
| + return gfx::Point3F(x() * inv_w, y() * inv_w, z() * inv_w);
|
| + }
|
| +
|
| + SkMScalar x() const { return vec[0]; }
|
| + SkMScalar y() const { return vec[1]; }
|
| + SkMScalar z() const { return vec[2]; }
|
| + SkMScalar w() const { return vec[3]; }
|
| +
|
| + SkMScalar vec[4];
|
| +};
|
| +
|
| +class MathUtil {
|
| + public:
|
| + static const double kPiDouble;
|
| + static const float kPiFloat;
|
| +
|
| + static double Deg2Rad(double deg) { return deg * kPiDouble / 180.0; }
|
| + static double Rad2Deg(double rad) { return rad * 180.0 / kPiDouble; }
|
| +
|
| + static float Deg2Rad(float deg) { return deg * kPiFloat / 180.0f; }
|
| + static float Rad2Deg(float rad) { return rad * 180.0f / kPiFloat; }
|
| +
|
| + static float Round(float f) {
|
| + return (f > 0.f) ? std::floor(f + 0.5f) : std::ceil(f - 0.5f);
|
| + }
|
| + static double Round(double d) {
|
| + return (d > 0.0) ? std::floor(d + 0.5) : std::ceil(d - 0.5);
|
| + }
|
| +
|
| + template <typename T> static T ClampToRange(T value, T min, T max) {
|
| + return std::min(std::max(value, min), max);
|
| + }
|
| +
|
| + // Background: Existing transform code does not do the right thing in
|
| + // MapRect / MapQuad / ProjectQuad when there is a perspective projection that
|
| + // causes one of the transformed vertices to go to w < 0. In those cases, it
|
| + // is necessary to perform clipping in homogeneous coordinates, after applying
|
| + // the transform, before dividing-by-w to convert to cartesian coordinates.
|
| + //
|
| + // These functions return the axis-aligned rect that encloses the correctly
|
| + // clipped, transformed polygon.
|
| + static gfx::Rect MapEnclosingClippedRect(const gfx::Transform& transform,
|
| + const gfx::Rect& rect);
|
| + static gfx::RectF MapClippedRect(const gfx::Transform& transform,
|
| + const gfx::RectF& rect);
|
| + static gfx::Rect ProjectEnclosingClippedRect(const gfx::Transform& transform,
|
| + const gfx::Rect& rect);
|
| + static gfx::RectF ProjectClippedRect(const gfx::Transform& transform,
|
| + const gfx::RectF& rect);
|
| +
|
| + // This function is only valid when the transform preserves 2d axis
|
| + // alignment and the resulting rect will not be clipped.
|
| + static gfx::Rect MapEnclosedRectWith2dAxisAlignedTransform(
|
| + const gfx::Transform& transform,
|
| + const gfx::Rect& rect);
|
| +
|
| + // Returns an array of vertices that represent the clipped polygon. After
|
| + // returning, indexes from 0 to num_vertices_in_clipped_quad are valid in the
|
| + // clipped_quad array. Note that num_vertices_in_clipped_quad may be zero,
|
| + // which means the entire quad was clipped, and none of the vertices in the
|
| + // array are valid.
|
| + static void MapClippedQuad(const gfx::Transform& transform,
|
| + const gfx::QuadF& src_quad,
|
| + gfx::PointF clipped_quad[8],
|
| + int* num_vertices_in_clipped_quad);
|
| + static bool MapClippedQuad3d(const gfx::Transform& transform,
|
| + const gfx::QuadF& src_quad,
|
| + gfx::Point3F clipped_quad[8],
|
| + int* num_vertices_in_clipped_quad);
|
| +
|
| + static gfx::RectF ComputeEnclosingRectOfVertices(const gfx::PointF vertices[],
|
| + int num_vertices);
|
| + static gfx::RectF ComputeEnclosingClippedRect(
|
| + const HomogeneousCoordinate& h1,
|
| + const HomogeneousCoordinate& h2,
|
| + const HomogeneousCoordinate& h3,
|
| + const HomogeneousCoordinate& h4);
|
| +
|
| + // NOTE: These functions do not do correct clipping against w = 0 plane, but
|
| + // they correctly detect the clipped condition via the boolean clipped.
|
| + static gfx::QuadF MapQuad(const gfx::Transform& transform,
|
| + const gfx::QuadF& quad,
|
| + bool* clipped);
|
| + static gfx::QuadF MapQuad3d(const gfx::Transform& transform,
|
| + const gfx::QuadF& q,
|
| + gfx::Point3F* p,
|
| + bool* clipped);
|
| + static gfx::PointF MapPoint(const gfx::Transform& transform,
|
| + const gfx::PointF& point,
|
| + bool* clipped);
|
| + static gfx::Point3F MapPoint(const gfx::Transform&,
|
| + const gfx::Point3F&,
|
| + bool* clipped);
|
| + static gfx::QuadF ProjectQuad(const gfx::Transform& transform,
|
| + const gfx::QuadF& quad,
|
| + bool* clipped);
|
| + static gfx::PointF ProjectPoint(const gfx::Transform& transform,
|
| + const gfx::PointF& point,
|
| + bool* clipped);
|
| + // Identical to the above function, but coerces the homogeneous coordinate to
|
| + // a 3d rather than a 2d point.
|
| + static gfx::Point3F ProjectPoint3D(const gfx::Transform& transform,
|
| + const gfx::PointF& point,
|
| + bool* clipped);
|
| +
|
| + static gfx::Vector2dF ComputeTransform2dScaleComponents(const gfx::Transform&,
|
| + float fallbackValue);
|
| +
|
| + // Makes a rect that has the same relationship to input_outer_rect as
|
| + // scale_inner_rect has to scale_outer_rect. scale_inner_rect should be
|
| + // contained within scale_outer_rect, and likewise the rectangle that is
|
| + // returned will be within input_outer_rect at a similar relative, scaled
|
| + // position.
|
| + static gfx::RectF ScaleRectProportional(const gfx::RectF& input_outer_rect,
|
| + const gfx::RectF& scale_outer_rect,
|
| + const gfx::RectF& scale_inner_rect);
|
| +
|
| + // Returns the smallest angle between the given two vectors in degrees.
|
| + // Neither vector is assumed to be normalized.
|
| + static float SmallestAngleBetweenVectors(const gfx::Vector2dF& v1,
|
| + const gfx::Vector2dF& v2);
|
| +
|
| + // Projects the |source| vector onto |destination|. Neither vector is assumed
|
| + // to be normalized.
|
| + static gfx::Vector2dF ProjectVector(const gfx::Vector2dF& source,
|
| + const gfx::Vector2dF& destination);
|
| +
|
| + // Conversion to value.
|
| + static scoped_ptr<base::Value> AsValue(const gfx::Size& s);
|
| + static scoped_ptr<base::Value> AsValue(const gfx::Rect& r);
|
| + static bool FromValue(const base::Value*, gfx::Rect* out_rect);
|
| + static scoped_ptr<base::Value> AsValue(const gfx::PointF& q);
|
| +
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::Size& s,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::SizeF& s,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::Rect& r,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::PointF& q,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::Point3F&,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::Vector2d& v,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::Vector2dF& v,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::ScrollOffset& v,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::QuadF& q,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::RectF& rect,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::Transform& transform,
|
| + base::trace_event::TracedValue* res);
|
| + static void AddToTracedValue(const char* name,
|
| + const gfx::BoxF& box,
|
| + base::trace_event::TracedValue* res);
|
| +
|
| + // Returns a base::Value representation of the floating point value.
|
| + // If the value is inf, returns max double/float representation.
|
| + static double AsDoubleSafely(double value);
|
| + static float AsFloatSafely(float value);
|
| +};
|
| +
|
| +} // namespace cc
|
| +
|
| +#endif // CC_BASE_MATH_UTIL_H_
|
|
|