12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CC_BASE_MATH_UTIL_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CC_BASE_MATH_UTIL_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <algorithm>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <cmath>
105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <vector>
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/cc_export.h"
15f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/box_f.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/point3_f.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/point_f.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/size.h"
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/transform.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace base {
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class Value;
235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace debug {
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TracedValue;
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gfx {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class QuadF;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Rect;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class RectF;
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Transform;
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class Vector2dF;
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class Vector2d;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct HomogeneousCoordinate {
40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  HomogeneousCoordinate(SkMScalar x, SkMScalar y, SkMScalar z, SkMScalar w) {
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    vec[0] = x;
42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    vec[1] = y;
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    vec[2] = z;
44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    vec[3] = w;
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
47a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool ShouldBeClipped() const { return w() <= 0.0; }
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::PointF CartesianPoint2d() const {
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (w() == SK_MScalar1)
51a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return gfx::PointF(x(), y());
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For now, because this code is used privately only by MathUtil, it should
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // never be called when w == 0, and we do not yet need to handle that case.
55a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DCHECK(w());
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SkMScalar inv_w = SK_MScalar1 / w();
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return gfx::PointF(x() * inv_w, y() * inv_w);
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  gfx::Point3F CartesianPoint3d() const {
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    if (w() == SK_MScalar1)
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      return gfx::Point3F(x(), y(), z());
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // For now, because this code is used privately only by MathUtil, it should
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // never be called when w == 0, and we do not yet need to handle that case.
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    DCHECK(w());
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    SkMScalar inv_w = SK_MScalar1 / w();
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return gfx::Point3F(x() * inv_w, y() * inv_w, z() * inv_w);
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SkMScalar x() const { return vec[0]; }
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SkMScalar y() const { return vec[1]; }
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SkMScalar z() const { return vec[2]; }
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SkMScalar w() const { return vec[3]; }
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  SkMScalar vec[4];
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CC_EXPORT MathUtil {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const double kPiDouble;
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const float kPiFloat;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static double Deg2Rad(double deg) { return deg * kPiDouble / 180.0; }
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static double Rad2Deg(double rad) { return rad * 180.0 / kPiDouble; }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static float Deg2Rad(float deg) { return deg * kPiFloat / 180.0f; }
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static float Rad2Deg(float rad) { return rad * 180.0f / kPiFloat; }
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static float Round(float f) {
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (f > 0.f) ? std::floor(f + 0.5f) : std::ceil(f - 0.5f);
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static double Round(double d) {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return (d > 0.0) ? std::floor(d + 0.5) : std::ceil(d - 0.5);
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  template <typename T> static T ClampToRange(T value, T min, T max) {
987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return std::min(std::max(value, min), max);
997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Background: Existing transform code does not do the right thing in
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // MapRect / MapQuad / ProjectQuad when there is a perspective projection that
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // causes one of the transformed vertices to go to w < 0. In those cases, it
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is necessary to perform clipping in homogeneous coordinates, after applying
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the transform, before dividing-by-w to convert to cartesian coordinates.
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These functions return the axis-aligned rect that encloses the correctly
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // clipped, transformed polygon.
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static gfx::Rect MapEnclosingClippedRect(const gfx::Transform& transform,
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           const gfx::Rect& rect);
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::RectF MapClippedRect(const gfx::Transform& transform,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const gfx::RectF& rect);
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static gfx::Rect ProjectEnclosingClippedRect(const gfx::Transform& transform,
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                               const gfx::Rect& rect);
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::RectF ProjectClippedRect(const gfx::Transform& transform,
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                       const gfx::RectF& rect);
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This function is only valid when the transform preserves 2d axis
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // alignment and the resulting rect will not be clipped.
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  static gfx::Rect MapEnclosedRectWith2dAxisAlignedTransform(
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const gfx::Transform& transform,
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const gfx::Rect& rect);
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns an array of vertices that represent the clipped polygon. After
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // returning, indexes from 0 to num_vertices_in_clipped_quad are valid in the
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // clipped_quad array. Note that num_vertices_in_clipped_quad may be zero,
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // which means the entire quad was clipped, and none of the vertices in the
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // array are valid.
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static void MapClippedQuad(const gfx::Transform& transform,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             const gfx::QuadF& src_quad,
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                             gfx::PointF clipped_quad[8],
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                             int* num_vertices_in_clipped_quad);
1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static bool MapClippedQuad3d(const gfx::Transform& transform,
1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               const gfx::QuadF& src_quad,
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               gfx::Point3F clipped_quad[8],
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               int* num_vertices_in_clipped_quad);
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static gfx::RectF ComputeEnclosingRectOfVertices(const gfx::PointF vertices[],
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                   int num_vertices);
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::RectF ComputeEnclosingClippedRect(
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const HomogeneousCoordinate& h1,
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const HomogeneousCoordinate& h2,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const HomogeneousCoordinate& h3,
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const HomogeneousCoordinate& h4);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // NOTE: These functions do not do correct clipping against w = 0 plane, but
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // they correctly detect the clipped condition via the boolean clipped.
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::QuadF MapQuad(const gfx::Transform& transform,
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const gfx::QuadF& quad,
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            bool* clipped);
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static gfx::QuadF MapQuad3d(const gfx::Transform& transform,
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              const gfx::QuadF& q,
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              gfx::Point3F* p,
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              bool* clipped);
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::PointF MapPoint(const gfx::Transform& transform,
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                              const gfx::PointF& point,
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              bool* clipped);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::Point3F MapPoint(const gfx::Transform&,
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const gfx::Point3F&,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               bool* clipped);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::QuadF ProjectQuad(const gfx::Transform& transform,
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                const gfx::QuadF& quad,
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                bool* clipped);
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::PointF ProjectPoint(const gfx::Transform& transform,
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                  const gfx::PointF& point,
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  bool* clipped);
167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // Identical to the above function, but coerces the homogeneous coordinate to
168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // a 3d rather than a 2d point.
169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  static gfx::Point3F ProjectPoint3D(const gfx::Transform& transform,
170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     const gfx::PointF& point,
171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                     bool* clipped);
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static gfx::Vector2dF ComputeTransform2dScaleComponents(const gfx::Transform&,
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                          float fallbackValue);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Makes a rect that has the same relationship to input_outer_rect as
177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // scale_inner_rect has to scale_outer_rect. scale_inner_rect should be
178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // contained within scale_outer_rect, and likewise the rectangle that is
179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // returned will be within input_outer_rect at a similar relative, scaled
180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // position.
181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  static gfx::RectF ScaleRectProportional(const gfx::RectF& input_outer_rect,
182424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                          const gfx::RectF& scale_outer_rect,
183424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)                                          const gfx::RectF& scale_inner_rect);
184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns the smallest angle between the given two vectors in degrees.
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Neither vector is assumed to be normalized.
1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static float SmallestAngleBetweenVectors(const gfx::Vector2dF& v1,
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                           const gfx::Vector2dF& v2);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Projects the |source| vector onto |destination|. Neither vector is assumed
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to be normalized.
1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static gfx::Vector2dF ProjectVector(const gfx::Vector2dF& source,
1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                      const gfx::Vector2dF& destination);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Conversion to value.
1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static scoped_ptr<base::Value> AsValue(const gfx::Size& s);
1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static scoped_ptr<base::Value> AsValue(const gfx::Rect& r);
19890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static bool FromValue(const base::Value*, gfx::Rect* out_rect);
1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static scoped_ptr<base::Value> AsValue(const gfx::PointF& q);
2005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void AddToTracedValue(const gfx::Size& s,
2025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::debug::TracedValue* res);
2035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void AddToTracedValue(const gfx::SizeF& s,
2045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::debug::TracedValue* res);
2055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void AddToTracedValue(const gfx::Rect& r,
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::debug::TracedValue* res);
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void AddToTracedValue(const gfx::PointF& q,
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::debug::TracedValue* res);
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void AddToTracedValue(const gfx::Point3F&,
2105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::debug::TracedValue* res);
2115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void AddToTracedValue(const gfx::Vector2d& v,
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::debug::TracedValue* res);
2136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  static void AddToTracedValue(const gfx::Vector2dF& v,
2146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                               base::debug::TracedValue* res);
2155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void AddToTracedValue(const gfx::QuadF& q,
2165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::debug::TracedValue* res);
2175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void AddToTracedValue(const gfx::RectF& rect,
2185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::debug::TracedValue* res);
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void AddToTracedValue(const gfx::Transform& transform,
2205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::debug::TracedValue* res);
2215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static void AddToTracedValue(const gfx::BoxF& box,
2225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                               base::debug::TracedValue* res);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Returns a base::Value representation of the floating point value.
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If the value is inf, returns max double/float representation.
2265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static double AsDoubleSafely(double value);
2275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  static float AsFloatSafely(float value);
2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CC_BASE_MATH_UTIL_H_
233